home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer)…68k, x86, SPARC, PA-RISC] / NeXTSTEP 3.3 Dev Intel.iso / NextLibrary / Documentation / NextDev / OperatingSystem / Part1_Mach / 04_MachFunctions / MachFunctions.rtf < prev   
Encoding:
Text File  |  1995-01-27  |  300.6 KB  |  4,586 lines

  1. {\rtf0\ansi\paperw16228 \paperh18648 \margl-907 \margr0 \margt0 \margb0 
  2. {\colortbl;\red0\green0\blue0;\red255\green255\blue255;\red255\green0\blue0;\red0\green255\blue0;\red0\green0\blue255;\red0\green255\blue255;\red255\green0\blue255;\red255\green255\blue0;
  3. }
  4. {\fonttbl\f0\fswiss Helvetica;\f1\froman Times;\f2\fmodern Courier;\f3\ftech Symbol;\f4\froman Palatino;}
  5. {\stylesheet{\s0 \li100 \fi0 \ri1007 \ql   1Head;}
  6. {\s1 \li2116 \fi0 \ri1007 \ql   2Head;}
  7. {\s2 \li2116 \fi0 \ri1007 \ql   3Head;}
  8. {\s3 \li2116 \fi0 \ri1007 \ql   4Head;}
  9. {\s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250   Body;}
  10. {\s5 \li2494 \fi0 \ri1007 \ql \tx2872 \tx3250 \tx3642   BodyIndented;}
  11. {\s6 \li2494 \fi-378 \ri1007 \ql \tx2494 \tx2872 \tx3250   BulletLong;}
  12. {\s7 \li2872 \fi-378 \ri1007 \ql \tx2872 \tx3250 \tx3628   BulletLongInd;}
  13. {\s8 \li2494 \fi-378 \ri1007 \ql \tx2494 \tx2872 \tx3250   BulletShort;}
  14. {\s9 \li0 \fi0 \ri0 \ql   Callout;}
  15. {\s10 \li100 \fi0 \ri0 \ql   ChapterNum;}
  16. {\s11 \li0 \fi0 \ri1007 \ql   ChapterTitle;}
  17. {\s12 \li2494 \fi0 \ri1007 \ql   CodeExamp;}
  18. {\s13 \li2872 \fi0 \ri1007 \ql   CodeExamp2;}
  19. {\s14 \li2116 \fi0 \ri503 \ql   CodeExampNoInd;}
  20. {\s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116   FctArgument;}
  21. {\s16 \li2116 \fi-2015 \ri1007 \ql   FctDescription;}
  22. {\s17 \li2116 \fi-2015 \ri1007 \ql   FctEquivalents;}
  23. {\s18 \li2116 \fi-2015 \ri1007 \ql   FctExample;}
  24. {\s19 \li2116 \fi-2015 \ri1007 \ql   FctExampleNonCode;}
  25. {\s20 \li2116 \fi0 \ri1007 \ql   FctHead;}
  26. {\s21 \li2116 \fi0 \ri1007 \ql   FctHeadXRef;}
  27. {\s22 \li2116 \fi0 \ri1007 \ql   FctHeadXRefShort;}
  28. {\s23 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116   FctLibrary;}
  29. {\s24 \li2116 \fi-2015 \ri1007 \ql   FctMacro;}
  30. {\s25 \li2116 \fi-2015 \ri1007 \ql   FctReturn;}
  31. {\s26 \li2116 \fi-2015 \ri1007 \ql   FctSeeAlso;}
  32. {\s27 \li2116 \fi-2015 \ri1007 \ql   FctSummary;}
  33. {\s28 \li2116 \fi-2015 \ri1007 \ql   FctSynopsis;}
  34. {\s29 \li2116 \fi0 \ri1007 \ql   Fig1Caption;}
  35. {\s30 \li2116 \fi0 \ri1007 \ql   FigCaption;}
  36. {\s31 \li0 \fi0 \ri0 \ql   FigHead;}
  37. {\s32 \li0 \fi0 \ri0 \ql   Figure;}
  38. {\s33 \li0 \fi0 \ri0 \ql \tx-25 \tx8290 \tx9172   Footer;}
  39. {\s34 \li2494 \fi-378 \ri1007 \ql   Function;}
  40. {\s35 \li2872 \fi-378 \ri1007 \ql   FunctionInd;}
  41. {\s36 \li2116 \fi0 \ri1007 \ql   Important;}
  42. {\s37 \li2116 \fi0 \ri1007 \ql   Note;}
  43. {\s38 \li2494 \fi-378 \ri1007 \ql \tx2494 \tx2872 \tx3250   Num1Long;}
  44. {\s39 \li2494 \fi-378 \ri1007 \ql   Num1Short;}
  45. {\s40 \li2494 \fi-378 \ri1007 \ql   NumLong;}
  46. {\s41 \li2494 \fi-378 \ri1007 \ql   NumShort;}
  47. {\s42 \li2494 \fi-378 \ri1007 \ql   Step;}
  48. {\s43 \li2494 \fi-378 \ri1007 \ql   Step1;}
  49. {\s44 \li2494 \fi0 \ri1007 \ql \tx6148 \tx10180   TableBody1;}
  50. {\s45 \li6148 \fi-3654 \ri1007 \ql \tx6148 \tx10432   TableBody2;}
  51. {\s46 \li2494 \fi0 \ri1007 \ql \tx6148 \tx10180   TableHead;}
  52. {\s47 \li2116 \fi0 \ri1007 \ql   Tip;}
  53. {\s48 \li2116 \fi0 \ri1007 \ql   Warning;}
  54. }
  55. \li0 \fi0 \ri0 \ql \sb0 \f1 \fs24 
  56. Copyright \f3 \'e3\f1 1995 by NeXT Computer, Inc.  All Rights Reserved.\
  57. \
  58. \s10 \li100 \fi0 \ri0 \ql \gray409\cf7\f0 \b \fs84 \fs20 \
  59. \fs84 4\
  60. \fs48 \
  61. \fs84 \s11 \li0 \fi756 \fi0 \ri1007 \gray0\cf0\f1 \b0 \i \fs88 Mach Functions\
  62. \fs120 \
  63. \fs88 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i0 \fs28 This chapter gives detailed descriptions of the C functions provided by the NeXT Mach operating system.  It also describes some macros that behave like functions.  For this chapter, the functions and macros are divided into five groups:\
  64. \fs20 \
  65. \fs28 \s6 \li2494 \fi-378 \'b7    C-thread functions\'d0Use these to implement multiple threads in an application.\
  66. \fs20 \
  67. \fs28 \'b7    Mach kernel functions\'d0Use these to get access to the Mach operating system.\
  68. \fs20 \
  69. \fs28 \'b7    Bootstrap Server functions\'d0Use these to set up communication between the task that provides a local service and the tasks that use the service.  \
  70. \fs20 \
  71. \fs28 \'b7    Network Name Server functions\'d0Use these to set up communication between tasks that might not be on the same machine.  \
  72. \fs20 \
  73. \fs28 \'b7    Kernel-server loader functions\'d0Use these to load and unload loadable kernel servers, to add and delete servers to and from the kernel-server loader, and to get information about servers.  \
  74. \fs20 \
  75. \fs28 \s4 \li2116 \fi0 Within each section, functions are subgrouped with other functions that perform related tasks.  These subgroups are described in alphabetical order by the name of the first function listed in the subgroup.  Functions within subgroups are also listed alphabetically, with a pointer to the subgroup description.  \
  76. \fs20 \
  77. \fs28 For convenience, these functions are summarized in the \i NEXTSTEP Programming Interface Summary\i0 .  The summary lists functions by the same subgroups used in this chapter and combines several related subgroups under a heading such as \'aaBasic C-Thread Functions\'ba or \'aaTask Functions.\'ba  For each function, the summary shows the calling sequence.\
  78. \fs20 \
  79. \fs28 \pard \s0 \li100 \fi0 \ri1007 \ql \f0 \b \fs48 \fs60 \
  80. \fs48 C-Thread Functions\
  81. \fs28 \
  82. \fs48 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \f1 \b0 \fs28 These functions provide a C language interface to the low-level, language-independent primitives for manipulating threads of control.  \
  83. \fs20 \
  84. \fs28 In a multithreaded application, you should use the C-thread functions whenever possible, rather than Mach kernel functions.  If you need to call a Mach kernel function that requires a \b thread_t\b0  argument, you can find the Mach thread that corresponds to a particular C thread by calling \b cthread_thread()\b0 .\
  85. \fs20 \
  86. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 \fs60 \
  87. \fs28 condition_alloc(), mutex_alloc()\
  88. \fs20 \
  89. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  90. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Create a condition or mutex object\
  91. \fs28 \
  92. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/cthreads.h>\
  93. \fs10 \
  94. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 condition_t \b condition_alloc(\b0 void\b )\
  95. \b0 mutex_t \b mutex_alloc(\b0 void\b )\
  96. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  97. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The macros \b condition_alloc()\b0  and \b mutex_alloc()\b0  provide dynamic allocation of condition and mutex objects.  When you\'27re finished using these objects, you can deallocate them using \b condition_free()\b0  and \b mutex_free()\b0 .\
  98. \fs20 \
  99. \fs28 \s18 \f2 \fs24 \fs10 \
  100. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 my_condition = condition_alloc();\
  101. \fi0 my_mutex = mutex_alloc();\
  102. \s26 \fi-2015 \f1 \fs28 \fs28 \
  103. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b condition_init()\b0 , \b mutex_init()\b0 , \b condition_free()\b0 , \b mutex_free()\
  104. \fs20 \
  105. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  106. \fs28 condition_broadcast()\
  107. \fs20 \
  108. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  109. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Broadcast a condition\
  110. \fs28 \
  111. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/cthreads.h>\
  112. \fs10 \
  113. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 void \b condition_broadcast(\b0 condition_t \i c\b \i0 )\
  114. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  115. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The macro \b condition_broadcast()\b0  wakes up all threads that are waiting (with \b condition_wait()\b0 ) for the condition \i c\i0 .  This macro is similar to \b condition_signal()\b0 , except that \b condition_signal()\b0  doesn\'27t wake up every waiting thread.\
  116. \fs20 \
  117. \fs28 \s18 \f2 \fs24 \fs10 \
  118. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 any_t listen(any_t arg)\
  119. \fi0 \{\
  120. \fi0     mutex_lock(my_mutex);\
  121. \fi0     while(!data)\
  122. \fi0         condition_wait(my_condition, my_mutex);\
  123. \fi0     /* . . . */\
  124. \fi0     mutex_unlock(my_mutex);\
  125. \fi0 \
  126. \fi0     mutex_lock(printing);\
  127. \fi0     printf("Condition has been met\\n");\
  128. \fi0     mutex_unlock(printing);\
  129. \fi0 \}\
  130. \pard \s14 \li2116 \fi0 \ri503 \ql \
  131. main()\
  132. \fi0 \{\
  133. \fi0     my_condition = condition_alloc();\
  134. \fi0     my_mutex = mutex_alloc();\
  135. \fi0     printing = mutex_alloc();\
  136. \fi0     \
  137. \fi0     cthread_detach(cthread_fork((cthread_fn_t)listen, (any_t)0));\
  138. \fi0     \
  139. \fi0     mutex_lock(my_mutex);\
  140. \fi0     data = 1;\
  141. \fi0     mutex_unlock(my_mutex);\
  142. \fi0     condition_broadcast(my_condition);\
  143. \fi0     /* . . . */\
  144. \fi0 \}\
  145. \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  146. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b condition_signal()\b0 , \b condition_wait()\
  147. \fs20 \
  148. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  149. \fs28 condition_clear(), mutex_clear()\
  150. \fs20 \
  151. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  152. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Clear a condition or mutex object\
  153. \fs28 \
  154. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/cthreads.h>\
  155. \fs10 \
  156. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 void \b condition_clear(\b0 struct condition *\i c\b \i0 )\
  157. \b0 void \b mutex_clear(\b0 struct mutex *\i m\b \i0 )\
  158. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  159. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 You must call one of these macros before freeing an object of type\b  struct condition\b0  or \b struct mutex\b0 .  See the discussion of \b condition_init()\b0  and \b mutex_init()\b0  for information on why you might want to use these types instead of \b condition_t\b0  and \b mutex_t\b0 .\
  160. \fs20 \
  161. \fs28 \s18 \f2 \fs24 \fs10 \
  162. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 struct mystruct \{\
  163. \fi0     my_data_t     data;\
  164. \fi0     struct mutex  m;\
  165. \fi0 \};\
  166. \fi0 struct mystruct  *mydata;\
  167. \fi0 mydata = (struct mystruct *)malloc(sizeof (struct mystruct));\
  168. \fi0 \
  169. \fi0 mutex_init(&mydata->m);\
  170. \fi0 /* . . . */\
  171. \fi0 mutex_lock(&mydata->m);\
  172. \fi0 /* Do something to mydata that only one thread can do. */\
  173. \fi0 mutex_unlock(&mydata->m);\
  174. \fi0 /* . . . */\
  175. \fi0 mutex_clear(&mydata->m);\
  176. \fi0 free(mydata);\
  177. \s26 \fi-2015 \f1 \fs28 \fs28 \
  178. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b condition_init()\b0 , \b mutex_init()\b0 , \b condition_free()\b0 , \b mutex_free()\
  179. \fs20 \
  180. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  181. \fs28 condition_free(),\b0  \b mutex\fs28 _\fs28 free()\
  182. \fs20 \
  183. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  184. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Deallocate a condition or mutex object\
  185. \fs28 \
  186. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/cthreads.h>\
  187. \fs10 \
  188. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 void \b condition_free(\b0 condition_t \i c\b \i0 )\
  189. \b0 void \b mutex_free(\b0 mutex_t \i m\b \i0 )\
  190. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  191. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The macros \b condition_free()\b0  and \b mutex_free()\b0  let you deallocate condition and mutex objects that were allocated dynamically.  Before deallocating such an object, you must guarantee that no other thread will reference it.  In particular, a thread blocked in \b mutex_lock()\b0  or \b condition_wait()\b0  should be viewed as referencing the object continually; freeing the object out from under such a thread is erroneous, and can result in bugs that are extremely difficult to track down.\
  192. \fs20 \
  193. \fs28 \s26 \fs10 \
  194. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b condition_alloc()\b0 , \b mutex_alloc()\b0 , \b condition_clear()\b0 , \b mutex_clear()\
  195. \fs20 \
  196. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  197. \fs28 condition_init(), mutex_init()\
  198. \fs20 \
  199. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  200. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Initialize a condition variable or mutex\
  201. \fs28 \
  202. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/cthreads.h>\
  203. \fs10 \
  204. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 void \b condition_init(\b0 struct condition *\i c\b \i0 )\
  205. \b0 void \b mutex_init(\b0 struct mutex *\i m\b \i0 )\
  206. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  207. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The macros \b condition_init()\b0  and \b mutex_init()\b0  initialize an object of the \b struct condition\b0  or \b struct mutex\b0  referent type, so that its address can be used wherever an object of type \b condition_t\b0  or \b mutex_t\b0  is expected.  Initialization of the referent type is most often used when you have included the referent type itself (rather than a pointer) in a larger structure, for more efficient storage allocation.\
  208. \fs20 \
  209. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 For instance, a data structure might contain a component of type \b struct mutex\b0  to allow each instance of that structure to be locked independently.  During initialization of the instance, you would call \b mutex_init()\b0  on the \b struct mutex\b0  component.  The alternative of using a \b mutex_t\b0  component and initializing it using \b mutex_alloc()\b0  would be less efficient.\
  210. \fs20 \
  211. \fs28 If you\'27re going to free a condition or mutex object of type \b struct condition\b0  or \b struct mutex\b0 , you should first clear it using \b condition_clear()\b0  or \b mutex_clear()\b0 .\
  212. \fs20 \
  213. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  214. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 struct mystruct \{\
  215. \fi0     my_data_t     data;\
  216. \fi0     struct mutex  m;\
  217. \fi0 \};\
  218. \fi0 struct mystruct  *mydata;\
  219. \fi0 mydata = (struct mystruct *)malloc(sizeof (struct mystruct));\
  220. \fi0 \
  221. \fi0 mutex_init(&mydata->m);\
  222. \fi0 /* . . . */\
  223. \fi0 mutex_lock(&mydata->m);\
  224. \fi0 /* Do something to mydata that only one thread can do. */\
  225. \fi0 mutex_unlock(&mydata->m);\
  226. \fi0 /* . . . */\
  227. \fi0 mutex_clear(&mydata->m);\
  228. \fi0 free(mydata);\
  229. \s26 \fi-2015 \f1 \fs28 \fs28 \
  230. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b condition_alloc()\b0 , \b mutex_alloc()\b0 , \b condition_clear()\b0 , \b mutex_clear()\
  231. \fs20 \
  232. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  233. \fs28 condition_name(), condition_set_name(), mutex_name(), mutex_set_name()\
  234. \fs20 \
  235. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  236. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Associate a string with a condition or mutex variable\
  237. \fs28 \
  238. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/cthreads.h>\
  239. \fs10 \
  240. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 char *\b condition_name(\b0 condition_t \i c\b \i0 )\
  241. \b0 void \b condition_set_name(\b0 condition_t \i c\i0 , char *\i name\b \i0 )\
  242. \b0 char *\b mutex_name(\b0 mutex_t \i m\b \i0 )\
  243. \b0 void \b mutex_set_name(\b0 mutex_t \i m\i0 , char *\i name\b \i0 )\
  244. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  245. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 These macros let you associate a name with a condition or a mutex object.  The name is used when trace information is displayed.  You can also use this name for your own application-dependent purposes.\
  246. \fs20 \
  247. \fs28 \s18 \f2 \fs24 \fs10 \
  248. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 /* Do something if this is a "TYPE 1" condition. */\
  249. \fi0 if (strcmp(condition_name(c), "TYPE 1") == 0) \
  250. \fi0     /* Do something. */;\
  251. \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 \fs80 \
  252. \fs28 condition_signal()\
  253. \fs20 \
  254. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  255. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Signal a condition\
  256. \fs28 \
  257. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/cthreads.h>\
  258. \fs10 \
  259. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 void \b condition_signal(\b0 condition_t \i c\b \i0 )\
  260. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  261. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The macro \b condition_signal()\b0  should be called when one thread needs to indicate that the condition represented by the condition variable is now true.  If any other threads are waiting (using \b condition_wait()\b0 ), at least one of them will be awakened.  If no threads are waiting, nothing happens.  The macro \b condition_broadcast()\b0  is similar to this one, except that it wakes up \i all\i0  threads that are waiting.\
  262. \fs20 \
  263. \fs28 \s18 \f2 \fs24 \fs10 \
  264. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 any_t listen(any_t arg)\
  265. \fi0 \{\
  266. \fi0     mutex_lock(my_mutex);\
  267. \fi0     while(!data)\
  268. \fi0         condition_wait(my_condition, my_mutex);\
  269. \fi0     /* . . . */\
  270. \fi0     mutex_unlock(my_mutex);\
  271. \fi0 \
  272. \fi0     mutex_lock(printing);\
  273. \fi0     printf("Condition has been met\\n");\
  274. \fi0     mutex_unlock(printing);\
  275. \fi0 \}\
  276. \pard \s14 \li2116 \fi0 \ri503 \ql \
  277. main()\
  278. \fi0 \{\
  279. \fi0     my_condition = condition_alloc();\
  280. \fi0     my_mutex = mutex_alloc();\
  281. \fi0     printing = mutex_alloc();\
  282. \fi0     \
  283. \fi0     cthread_detach(cthread_fork((cthread_fn_t)listen, (any_t)0));\
  284. \fi0     \
  285. \fi0     mutex_lock(my_mutex);\
  286. \fi0     data = 1;\
  287. \fi0     mutex_unlock(my_mutex);\
  288. \fi0     condition_signal(my_condition);\
  289. \fi0     /* . . . */\
  290. \fi0 \}\
  291. \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  292. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b condition_broadcast()\b0 , \b condition_wait()\
  293. \fs20 \
  294. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  295. \fs28 condition_wait()\
  296. \fs20 \
  297. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  298. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Wait on a condition\
  299. \fs28 \
  300. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/cthreads.h>\
  301. \fs10 \
  302. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 void \b condition_wait(\b0 condition_t \i c\i0 , mutex_t \i m\b \i0 )\
  303. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  304. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b condition_wait()\b0  unlocks the mutex it takes as a argument, suspends the calling thread until the specified condition is likely to be true, and locks the mutex again when the thread resumes.  There\'27s no guarantee that the condition will be true when the thread resumes, so this function should always be used as follows:\
  305. \fs20 \
  306. \fs28 \pard \s12 \li2494 \fi0 \ri1007 \ql \f2 \fs24 mutex_t m;\
  307. \fi0 condition_t c;\
  308. \fi0 \
  309. \fi0 mutex_lock(m);\
  310. \fi0 /* . . . */\
  311. \fi0 while    (/* condition isn\'27t true */)\
  312. \fi0     condition_wait(c, m);\
  313. \fi0 /* . . . */\
  314. \fi0 mutex_unlock(m);\
  315. \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  316. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b condition_broadcast()\b0 , \b condition_signal()\
  317. \fs20 \
  318. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  319. \fs28 cthread_abort()\
  320. \fs20 \
  321. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  322. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Interrupt a C thread\
  323. \fs28 \
  324. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/cthreads.h>\
  325. \fs10 \
  326. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b cthread_abort(\b0 cthread_t\b  \b0 \i t\b \i0 )\
  327. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  328. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 This function provides the functionality of \b thread_abort()\b0  to C threads.  The \b cthread_abort()\b0  function interrupts system calls; it\'27s usually used along with \b thread_suspend()\b0 , which stops a thread from executing any more user code.  Calling \b cthread_abort()\b0  on a thread that isn\'27t suspended is risky, since it\'27s difficult to know exactly what system trap, if any, the thread might be executing and whether an interrupt return would cause the thread to do something useful.\
  329. \fs20 \
  330. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 See \b thread_abort()\b0  for a full description of the use of this function.\
  331. \fs20 \
  332. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 \fs60 \
  333. \fs28 cthread_count()\
  334. \fs20 \
  335. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  336. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get the number of threads in this task\
  337. \fs28 \
  338. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/cthreads.h>\
  339. \fs10 \
  340. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 int \b cthread_count()\
  341. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  342. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 This function returns the number of threads that exist in the current task.  You can use this function to help make sure that your task doesn\'27t create too many threads (over 200 or so).  See \b cthread_set_limit()\b0  for information on restricting the number of threads in a task.\
  343. \fs20 \
  344. \fs28 \s18 \f2 \fs24 \fs10 \
  345. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 printf("C thread count should be 1, is %d\\n", cthread_count());\
  346. \fi0 cthread_detach(cthread_fork((cthread_fn_t)listen, (any_t)0));\
  347. \fi0 printf("C thread count should be 2, is %d\\n", cthread_count());\
  348. \s26 \fi-2015 \f1 \fs28 \fs28 \
  349. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b cthread_limit()\b0 , \b cthread_set_limit()\
  350. \fs20 \
  351. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  352. \fs28 cthread_data(),\b0  \b cthread_set_data()\
  353. \fs20 \
  354. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  355. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Associate data with a thread\
  356. \fs28 \
  357. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/cthreads.h>\
  358. \fs10 \
  359. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 any_t \b cthread_data(\b0 cthread_t \i t\b \i0 )\
  360. \b0 void \b cthread_set_data(\b0 cthread_t \i t\i0 , any_t \i data\b \i0 )\
  361. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  362. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The macros \b cthread_data()\b0  and \b cthread_set_data()\b0  let you associate arbitrary data with a thread, providing a simple form of thread-specific \'aaglobal\'ba variable.  More elaborate mechanisms, such as per-thread property lists or hash tables, can then be built with these macros.\
  363. \fs20 \
  364. \fs28 \s18 \f2 \fs24 \fs10 \
  365. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 int listen(any_t arg)\
  366. \fi0 \{\
  367. \fi0     mutex_lock(printing);\
  368. \fi0     printf("This thread\'27s data is: %d\\n",\
  369. \fi0         (int)cthread_data(cthread_self()));\
  370. \fi0     mutex_unlock(printing);\
  371. \fi0     /* . . . */\
  372. \fi0 \}\
  373. \pard \s14 \li2116 \fi0 \ri503 \ql \
  374. main()\
  375. \fi0 \{\
  376. \fi0     cthread_t lthread;\
  377. \fi0     \
  378. \fi0     printing = mutex_alloc();\
  379. \fi0     \
  380. \fi0     lthread = cthread_fork((cthread_fn_t)listen, (any_t)0);\
  381. \fi0     cthread_set_data(lthread, (any_t)100);\
  382. \fi0     cthread_detach(lthread);\
  383. \fi0     /* . . . */\
  384. \fi0 \}\
  385. \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  386. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b cthread_name()\b0 , \b cthread_set_name()\
  387. \fs20 \
  388. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  389. \fs28 cthread_detach()\
  390. \fs20 \
  391. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  392. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Detach a thread\
  393. \fs28 \
  394. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/cthreads.h>\
  395. \fs10 \
  396. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 void \b cthread_detach(\b0 cthread_t \i t\b \i0 )\
  397. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  398. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b cthread_detach()\b0  is used to indicate that \b cthread_join()\b0  will never be called on the given thread.  This is usually known at the time the thread is forked, so the most efficient usage is the following:\
  399. \fs20 \
  400. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250     \b cthread_detach(cthread_fork\b0 (\i function\i0 , \i argument\i0 )\b )\b0 ;\
  401. \fs20 \
  402. \fs28 A thread may, however, be detached at any time after it\'27s forked, as long as no other attempt is made to join it or detach it.\
  403. \fs20 \
  404. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  405. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 cthread_detach(cthread_fork((cthread_fn_t)listen, (any_t)reply_port));\
  406. \s26 \f1 \fs28 \fs28 \
  407. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b cthread_fork()\b0 , \b cthread_join()\
  408. \fs20 \
  409. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  410. \fs28 cthread_errno()\
  411. \fs20 \
  412. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  413. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get a thread\'27s errno value\
  414. \fs28 \
  415. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/cthreads.h>\
  416. \fs10 \
  417. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 int \b cthread_errno(\b0 void\b )\
  418. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  419. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 Use the \b cthread_errno()\b0  function to get the errno value for the current thread.  In the UNIX operating system, \b errno\b0  is a process-wide global variable that\'27s set to an error number when a UNIX system call fails.  However, because Mach has multiple threads per process, Mach keeps errno information on a per-thread basis as well as in \b errno\b0 .  \
  420. \fs20 \
  421. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Like the value of \b errno\b0 , the value returned by \b cthread_errno()\b0  is valid only if the last UNIX system call returned \f3 -\f1 1.  Errno values are defined in the header file \b bsd/sys/errno.h\b0 .\
  422. \fs20 \
  423. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  424. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 int ret;\
  425. \fi0 \
  426. \fi0 ret = chown(FILEPATH, newOwner, newGroup);\
  427. \fi0 if (ret == -1) \{\
  428. \fi0     if (cthread_errno() == ENAMETOOLONG)\
  429. \fi0         /* . . . */\
  430. \fi0 \}\
  431. \s26 \fi-2015 \f1 \fs28 \fs28 \
  432. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b cthread_set_errno()\b0 , \b intro(2) \b0 UNIX manual page\
  433. \fs20 \
  434. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 \fs60 \
  435. \fs28 cthread_exit()\
  436. \fs20 \
  437. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  438. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Exit a thread\
  439. \fs28 \
  440. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/cthreads.h>\
  441. \fs10 \
  442. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 void \b cthread_exit(\b0 any_t \i result\b \i0 )\
  443. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  444. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b cthread_exit()\b0  terminates the calling thread.  The result is passed to the thread that joins the caller, or is discarded if the caller is detached.\
  445. \fs20 \
  446. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 An implicit \b cthread_exit()\b0  occurs when the top-level function of a thread returns, but it may also be called explicitly.\
  447. \fs20 \
  448. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  449. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 cthread_exit(0);\
  450. \s26 \f1 \fs28 \fs28 \
  451. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b cthread_detach()\b0 , \b cthread_fork()\b0 , \b cthread_join()\
  452. \fs20 \
  453. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  454. \fs28 cthread_fork()\
  455. \fs20 \
  456. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  457. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Fork a thread\
  458. \fs28 \
  459. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/cthreads.h>\
  460. \fs10 \
  461. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 cthread_t \b cthread_fork(\b0 any_t (*\i function\i0 )(), any_t \i arg\b \i0 )\
  462. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  463. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b cthread_fork()\b0  takes two arguments:  a function for the new thread to execute, and an argument to this function.  The \b cthread_fork()\b0  function creates a new thread of control in which the specified function is executed concurrently with the caller\'27s thread.  This is the sole means of creating new threads.\
  464. \fs20 \
  465. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The \b any_t\b0  type represents a pointer to any C type.  The \b cthread_t\b0  type is an integer-size handle that uniquely identifies a thread of control.  Values of type \b cthread_t\b0  will be referred to as thread identifiers.  Arguments larger than a pointer must be passed by reference.  Similarly, multiple arguments must be simulated by passing a pointer to a structure containing several components.  The call to \b cthread_fork()\b0  returns a thread identifier that can be passed to \b cthread_join()\b0  or \b cthread_detach()\b0 .  Every thread must be either joined or detached exactly once.\
  466. \fs20 \
  467. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  468. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 cthread_detach(cthread_fork((cthread_fn_t)listen, (any_t)reply_port));\
  469. \s26 \f1 \fs28 \fs28 \
  470. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b cthread_detach()\b0 , \b cthread_exit()\b0 , \b cthread_join()\
  471. \fs20 \
  472. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  473. \fs28 cthread_join()\
  474. \fs20 \
  475. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  476. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Join threads\
  477. \fs28 \
  478. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/cthreads.h>\
  479. \fs10 \
  480. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 any_t \b cthread_join(\b0 cthread_t \i t\b \i0 )\
  481. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  482. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b cthread_join()\b0  suspends the caller until the specified thread \i t\i0  terminates.  The caller receives either the result of \i t\i0 \'27s top-level function or the argument with which \i t\i0  explicitly called \b cthread_exit()\b0 .\
  483. \fs20 \
  484. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Attempting to join one\'27s own thread results in deadlock.\
  485. \fs20 \
  486. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  487. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 cthread_t t;\
  488. \fi0 t = cthread_fork((any_t (*)())listen, (any_t)reply_port);\
  489. \fi0 /* . . . (Do some work, perhaps forking other threads.) */\
  490. \fi0 result = cthread_join(t);  /* Wait for the thread to finish executing. */\
  491. \fi0 /* . . . (Continue doing work) */\
  492. \s26 \fi-2015 \f1 \fs28 \fs28 \
  493. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b cthread_detach()\b0 , \b cthread_exit()\b0 , \b cthread_fork()\
  494. \fs20 \
  495. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  496. \fs28 cthread_limit(), cthread_set_limit()\
  497. \fs20 \
  498. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  499. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get or set the maximum number of threads in this task\
  500. \fs28 \
  501. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/cthreads.h>\
  502. \fs10 \
  503. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 int \b cthread_limit(\b0 void\b )\
  504. \b0 void \b cthread_set_limit(\b0 int \i limit\b \i0 )\
  505. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  506. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i limit\i0 :  The new maximum number of C threads per task.  Specify zero if you want no limit.\
  507. \fs20 \
  508. \fs28 \s16 \fs10 \
  509. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 These functions can help you to avoid creating too many threads.  The danger in creating a large number of threads is that the kernel might run out of resources and panic.  Usually, a task should avoid creating more than about 200 threads.\
  510. \fs20 \
  511. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Use \b cthread_set_limit()\b0  to set a limit on the number of threads in the current task.  When the limit is reached, new C threads will appear to fork successfully.  However, they will have no associated Mach thread, so they won\'27t do anything.\
  512. \fs20 \
  513. \fs28 Use \b cthread_limit()\b0  to find out how many threads can exist in the current task.  If the returned value is zero (the default), then no limit is currently being enforced.\
  514. \fs20 \
  515. \fs28 \pard \s36 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Important:  \b0 \fs28 \f1 Use \b cthread_count()\b0  to determine when your task is approaching the maximum number of threads.\
  516. \fs20 \
  517. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  518. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 cthread_set_limit(LIMIT);\
  519. \fi0 \
  520. \fi0 /* . . . */\
  521. \fi0 \
  522. \fi0 /* Fork if we haven\'27t reached the limit. */\
  523. \fi0 if ( (LIMIT == 0) || (LIMIT > cthread_count()) )\
  524. \fi0     cthread_detach(cthread_fork((any_t (*)())a_thread,(any_t)0));\
  525. \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 \fs80 \
  526. \fs28 cthread_name(),\b0  \b cthread_set_name()\
  527. \fs20 \
  528. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  529. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Associate a string with a thread \
  530. \fs28 \
  531. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/cthreads.h>\
  532. \fs10 \
  533. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 char *\b cthread_name(\b0 cthread_t \i t\b \i0 )\
  534. \b0 void \b cthread_set_name(\b0 cthread_t \i t\i0 , char *\i name\b \i0 )\
  535. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  536. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The functions \b cthread_name()\b0  and \b cthread_set_name()\b0  let you associate an arbitrary name with a thread.  The name is used when trace information is displayed.  The name may also be used for application-specific diagnostics.\
  537. \fs20 \
  538. \fs28 \s18 \f2 \fs24 \fs10 \
  539. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 int listen(any_t arg)\
  540. \fi0 \{\
  541. \fi0     mutex_lock(printing);\
  542. \fi0     printf("This thread\'27s name is: %s\\n",\
  543. \fi0         cthread_name(cthread_self()));\
  544. \fi0     mutex_unlock(printing);\
  545. \fi0     /* . . . */\
  546. \fi0 \}\
  547. \pard \s14 \li2116 \fi0 \ri503 \ql \
  548. main()\
  549. \fi0 \{\
  550. \fi0     cthread_t lthread;\
  551. \fi0     \
  552. \fi0     printing = mutex_alloc();\
  553. \fi0     \
  554. \fi0     lthread = cthread_fork((cthread_fn_t)listen, (any_t)0);\
  555. \fi0     cthread_set_name(lthread, "lthread");\
  556. \fi0     cthread_detach(lthread);\
  557. \fi0     /* . . . */\
  558. \fi0 \}\
  559. \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  560. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b cthread_data()\b0 , \b cthread_set_data()\
  561. \fs20 \
  562. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  563. \fs28 cthread_priority(), cthread_max_priority()\
  564. \fs20 \
  565. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  566. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Set the scheduling priority for a C thread\
  567. \fs28 \
  568. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/cthreads.h>\
  569. \fs10 \
  570. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b cthread_priority(\b0 cthread_t \i t\i0 , int \i priority\i0 , boolean_t \i set_max\b \i0 )\
  571. \b0 kern_return_t \b cthread_max_priority(\b0 cthread_t \i t\i0 , processor_set_t \i processor_set\i0 , int \i max_priority\b \i0 )\
  572. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  573. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i t\i0 :  The C thread whose priority is to be changed.\
  574. \fs20 \
  575. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i priority\i0 :  The new priority to change it to.\
  576. \fs20 \
  577. \fs28 \i set_max\i0 :  Also set \i t\i0 \'27s maximum priority if true.\
  578. \fs20 \
  579. \fs28 \i processor_set\i0 :  The privileged port for the processor set to which \i thread\i0  is currently assigned.\
  580. \fs20 \
  581. \fs28 \i max_priority\i0 :  The new maximum priority.\
  582. \fs20 \
  583. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  584. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 These functions give C threads the functionality of \b thread_priority()\b0  and \b thread_max_priority()\b0 .  See those functions for more details than are provided here.\
  585. \fs20 \
  586. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The \b cthread_priority()\b0  function changes the base priority and (optionally) the maximum priority of \i t\i0 .  If the new base priority is higher than the\i  \i0 scheduled\i  \i0 priority of the currently executing thread, this thread might be preempted.  The maximum priority of the thread is also set if \i set_max\i0  is true.  This call fails if \i priority\i0  is greater than the current maximum priority of the thread.  As a result, \b cthread_priority()\b0  can lower\'d0but never raise\'d0the value of a thread\'27s maximum priority.\
  587. \fs20 \
  588. \fs28 The\b  cthread_max_priority()\b0  function changes the maximum priority of the thread.  Because it requires the privileged port for the processor set, this call can reset the maximum priority to any legal value.  If the new maximum priority is less than the thread\'27s base priority, then the thread\'27s base priority is set to the new maximum priority.\
  589. \fs20 \
  590. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  591. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 /* Get the privileged port for the default processor set. */\
  592. \fi0 error=processor_set_default(host_self(), &default_set);\
  593. \fi0 if (error!=KERN_SUCCESS) \{\
  594. \fi0     mach_error("Error calling processor_set_default()", error);\
  595. \fi0     exit(1);\
  596. \fi0 \}\
  597. \pard \s14 \li2116 \fi0 \ri503 \ql \
  598. error=host_processor_set_priv(host_priv_self(), default_set,\
  599. \fi0     &default_set_priv);\
  600. \fi0 if (error!=KERN_SUCCESS) \{\
  601. \fi0     mach_error("Call to host_processor_set_priv() failed", error);\
  602. \fi0     exit(1);\
  603. \fi0 \}\
  604. \fi0 \
  605. /* Set the max priority. */\
  606. \fi0 error=cthread_max_priority(cthread_self(), default_set_priv,\
  607. \fi0     priority);\
  608. \fi0 if (error!=KERN_SUCCESS)\
  609. \fi0     mach_error("Call to cthread_max_priority() failed",error);\
  610. \fi0 \
  611. /* Set the thread\'27s priority. */\
  612. \fi0 error=cthread_priority(cthread_self(), priority, FALSE);\
  613. \fi0 if (error!=KERN_SUCCESS)\
  614. \fi0     mach_error("Call to cthread_priority() failed",error);\
  615. \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  616. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  Operation completed successfully\
  617. \fs20 \
  618. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i cthread\i0  is not a C thread, \i processor_set\i0  is not a privileged port for a processor set, or \i priority\i0  is out of range (not in 0-31).\
  619. \fs20 \
  620. \fs28 KERN_FAILURE:  The requested operation would violate the thread\'27s maximum priority (only for \b cthread_priority()\b0 ) or the thread is not assigned to the processor set whose privileged port was presented.\
  621. \fs20 \
  622. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  623. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b thread_priority()\b0 , \b thread_max_priority()\b0 , \b thread_policy()\b0 , \b task_priority()\b0 , \b processor_set_priority()\
  624. \fs20 \
  625. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  626. \fs28 cthread_self()\
  627. \fs20 \
  628. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  629. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Return the caller\'27s C-thread identifier\
  630. \fs28 \
  631. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/cthreads.h>\
  632. \fs10 \
  633. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 cthread_t \b cthread_self(\b0 void\b )\
  634. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  635. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b cthread_self()\b0  returns the caller\'27s own C-thread identifier, which is the same value that was returned by \b cthread_fork()\b0  to the creator of the thread.  The C-thread identifier uniquely identifies the thread, and hence may be used as a key in data structures that associate user data with individual threads.  Since thread identifiers may be reused by the underlying implementation, you should be careful to clean up such associations when threads exit.\
  636. \fs20 \
  637. \fs28 \s18 \f2 \fs24 \fs10 \
  638. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 printf("This thread\'27s name is: %s\\n",\
  639. \fi0     cthread_name(cthread_self()));\
  640. \fi0 mutex_unlock(printing);\
  641. \s26 \fi-2015 \f1 \fs28 \fs28 \
  642. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b cthread_fork()\b0 , \b cthread_thread()\b0 , \b thread_self()\
  643. \fs20 \
  644. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  645. \fs28 cthread_set_errno_self()\
  646. \fs20 \
  647. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  648. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Set the current thread\'27s errno value\
  649. \fs28 \
  650. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/cthreads.h>\
  651. \fs10 \
  652. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 void \b cthread_set_errno_self(\b0 int \i error\b \i0 )\
  653. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  654. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 Use this function\i  \i0 to set the errno value for the current thread to \i error\i0 .  In the UNIX operating system, \b errno\b0  is a process-wide global variable that\'27s set to an error number when a UNIX system call fails.  However, because Mach has multiple threads per process, Mach keeps errno information on a per-thread basis as well as in \b errno\b0 .  This function has no effect on the value of \b errno\b0 .\
  655. \fs20 \
  656. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The current thread\'27s errno value can be obtained by calling \b cthread_errno()\b0 .  Errno values are defined in the header file \b bsd/sys/errno.h\b0 .\
  657. \fs20 \
  658. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  659. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 cthread_set_errno_self(EPERM);\
  660. \s26 \f1 \fs28 \fs28 \
  661. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b cthread_errno()\b0 , \b intro(2) \b0 UNIX manual page\
  662. \fs20 \
  663. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 \fs60 \
  664. \fs28 cthread_thread()\
  665. \fs20 \
  666. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  667. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Return the caller\'27s Mach thread identifier\
  668. \fs28 \
  669. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/cthreads.h>\
  670. \fs10 \
  671. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 thread_t \b cthread_thread(\b0 cthread_t \i t\b \i0 )\
  672. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  673. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The macro \b cthread_thread()\b0  returns the Mach thread that corresponds to the specified C thread \i t\i0 .\
  674. \fs20 \
  675. \fs28 \s18 \f2 \fs24 \fs10 \
  676. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 /* Save the cthread and thread values for the forked thread. */\
  677. \fi0 l_cthread = cthread_fork((cthread_fn_t)listen, (any_t)0);\
  678. \fi0 cthread_detach(l_cthread);\
  679. \fi0 l_realthread = cthread_thread(l_cthread);\
  680. \s26 \fi-2015 \f1 \fs28 \fs28 \
  681. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b cthread_fork()\b0 , \b cthread_self()\
  682. \fs20 \
  683. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  684. \fs28 cthread_yield()\
  685. \fs20 \
  686. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  687. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Yield the processor to other threads\
  688. \fs28 \
  689. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/cthreads.h>\
  690. \fs10 \
  691. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 void \b cthread_yield(\b0 void\b )\
  692. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  693. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b cthread_yield()\b0  is a hint to the scheduler, suggesting that this would be a convenient point to schedule another thread to run on the current processor.\
  694. \fs20 \
  695. \fs28 \s18 \f2 \fs24 \fs10 \
  696. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 int i, n;\
  697. \fi0 \
  698. \fi0 /* n is set previously */\
  699. \fi0 for (i = 0; i < n; i += 1)\
  700. \fi0     cthread_yield();\
  701. \s26 \fi-2015 \f1 \fs28 \fs28 \
  702. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b cthread_priority()\b0 , \b thread_switch()\
  703. \fs20 \
  704. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  705. \fs28 mutex_lock()\
  706. \fs20 \
  707. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  708. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Lock a mutex variable\
  709. \fs28 \
  710. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/cthreads.h>\
  711. \fs10 \
  712. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 void \b mutex_lock(\b0 mutex_t \i m\b \i0 )\
  713. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  714. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The macro \b mutex_lock()\b0  attempts to lock the mutex \i m\i0  and blocks until it succeeds.  If several threads attempt to lock the same mutex concurrently, one will succeed, and the others will block until \i m\i0  is unlocked.  A deadlock occurs if a thread attempts to lock a mutex it has already locked.\
  715. \fs20 \
  716. \fs28 \s18 \f2 \fs24 \fs10 \
  717. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 /* Only one thread at a time should call printf. */\
  718. \fi0 mutex_lock(printing);\
  719. \fi0 printf("Condition has been met\\n");\
  720. \fi0 mutex_unlock(printing);\
  721. \s26 \fi-2015 \f1 \fs28 \fs28 \
  722. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b mutex_try_lock()\b0 , \b mutex_unlock()\
  723. \fs20 \
  724. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  725. \fs28 mutex_try_lock()\
  726. \fs20 \
  727. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  728. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Try to lock a mutex variable\
  729. \fs28 \
  730. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/cthreads.h>\
  731. \fs10 \
  732. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 int \b mutex_try_lock(\b0 mutex_t \i m\b \i0 )\
  733. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  734. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b mutex_try_lock()\b0  attempts to lock the mutex \i m\i0 , like \b mutex_lock()\b0 , and returns true if it succeeds.  If \i m\i0  is already locked, however, \b mutex_try_lock()\b0  immediately returns false rather than blocking.  For example, a busy-waiting version of \b mutex_lock()\b0  could be written using \b mutex_try_lock()\b0 :\
  735. \fs20 \
  736. \fs28 \pard \s12 \li2494 \fi0 \ri1007 \ql \f2 \fs24 void mutex_lock(mutex_t m) \
  737. \fi0 \{\
  738. \fi0     for (;;)\
  739. \fi0         if (mutex_try_lock(m))\
  740. \fi0             return;\
  741. \fi0 \}\
  742. \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  743. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b mutex_lock()\b0 , \b mutex_unlock()\
  744. \fs20 \
  745. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  746. \fs28 mutex_unlock()\
  747. \fs20 \
  748. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  749. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Unlock a mutex variable\
  750. \fs28 \
  751. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/cthreads.h>\
  752. \fs10 \
  753. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 void \b mutex_unlock(\b0 mutex_t \i m\b \i0 )\
  754. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  755. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b mutex_unlock()\b0  unlocks \i m\i0 , giving other threads a chance to lock it.\
  756. \fs20 \
  757. \fs28 \s18 \f2 \fs24 \fs10 \
  758. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 /* Only one thread at a time should call printf. */\
  759. \fi0 mutex_lock(printing);\
  760. \fi0 printf("Condition has been met\\n");\
  761. \fi0 mutex_unlock(printing);\
  762. \s26 \fi-2015 \f1 \fs28 \fs28 \
  763. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b mutex_lock()\b0 , \b mutex_try_lock()\
  764. \fs20 \
  765. \fs28 \pard \s0 \li100 \fi0 \ri1007 \ql \f0 \fs48 \fs60 \
  766. \fs48 Mach Kernel Functions\
  767. \fs28 \
  768. \fs48 \s20 \li2116 \fi-2015 \fi0 \fs28 \fs52 \
  769. \fs28 exc_server()\
  770. \fs20 \
  771. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  772. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Dispatch a message received on an exception port\
  773. \fs28 \
  774. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  775. \fi0 #import <mach/exception.h>\
  776. \fs10 \
  777. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 boolean_t \b exc_server(\b0 msg_header_t *\i in\i0 , msg_header_t *\i out\b \i0 )\
  778. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  779. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i in\i0 :  A message that was received on the exception port.  This message structure should be at least 64 bytes long.\
  780. \fs20 \
  781. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i out\i0 :  An empty message to be filled by \b exc_server()\b0  and then sent.  This message buffer should be at least 32 bytes long.\
  782. \fs20 \
  783. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  784. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 This function calls the appropriate exception handler.  You should call this function after you\'27ve received a message on an exception port that you set up previously.  Usually, this function is used along with a user-defined exception handler, which must have the following protocol:\
  785. \fs20 \
  786. \fs28 \pard \s35 \li2872 \fi-378 \ri1007 \ql kern_return_t \b catch_exception_raise(\b0 port_t \i exception_port\i0 , port_t \i thread\i0 , port_t \i task\i0 , int \i exception\i0 , int \i code\i0 , int \i subcode\b \i0 )\
  787. \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \b0 \fs20 \
  788. \fs28 To receive a message on an exception port, you must first create a new port and make it the task or thread exception port.  (You can\'27t use the default task exception port because you can\'27t get receive rights for it.)  Before calling \b msg_receive()\b0 , you must set the \b local_port\b0  field of the header to the appropriate exception port and the \b msg_size\b0  field to the size of the structure for the incoming message.\
  789. \fs20 \
  790. \fs28 If it accepted the incoming message, \b exc_server()\b0  returns true; otherwise it returns false.\
  791. \fs20 \
  792. \fs28 You should keep a global value that indicates whether your exception handler successfully handled the exception.  If it couldn\'27t, then you should forward the exception message to the old exception port.\
  793. \fs20 \
  794. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  795. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 typedef struct \{\
  796. \fi0     port_t old_exc_port;\
  797. \fi0     port_t clear_port;\
  798. \fi0     port_t exc_port;\
  799. \fi0 \} ports_t;\
  800. \pard \s14 \li2116 \fi0 \ri503 \ql \
  801. volatile boolean_t  pass_on = FALSE;\
  802. \fi0 mutex_t             printing;\
  803. \fi0 \
  804. /* Listen on the exception port. */\
  805. \fi0 any_t exc_thread(ports_t *port_p)\
  806. \fi0 \{\
  807. \fi0     kern_return_t   r;\
  808. \fi0     char           *msg_data[2][64];\
  809. \fi0     msg_header_t   *imsg = (msg_header_t *)msg_data[0],\
  810. \fi0                    *omsg = (msg_header_t *)msg_data[1];\
  811. \fi0 \
  812.     /* Wait for exceptions. */\
  813. \fi0     while (1) \{\
  814. \fi0         imsg->msg_size = 64;\
  815. \fi0         imsg->msg_local_port = port_p->exc_port;\
  816. \fi0         r = msg_receive(imsg, MSG_OPTION_NONE, 0);\
  817. \fi0 \
  818.         if (r==RCV_SUCCESS) \{\
  819. \fi0             /* Give the message to the Mach exception server. */\
  820. \fi0             if (exc_server(imsg, omsg)) \{\
  821. \fi0                 /* Send the reply message that exc_serv gave us. */\
  822. \fi0                 r = msg_send(omsg, MSG_OPTION_NONE, 0);\
  823. \fi0                 if (r != SEND_SUCCESS) \{\
  824. \fi0                     mach_error("msg_send", r);\
  825. \fi0                     exit(1);\
  826. \fi0                 \}\
  827. \fi0             \}\
  828. \fi0             else \{ /* exc_server refused to handle imsg. */\
  829. \fi0                 mutex_lock(printing);\
  830. \fi0                 printf("exc_server didn\'27t like the message\\n");\
  831. \fi0                 mutex_unlock(printing);\
  832. \fi0                 exit(2);\
  833. \fi0             \}\
  834. \fi0         \}\
  835. \fi0         else \{ /* msg_receive() returned an error. */\
  836. \fi0                 mach_error("msg_receive", r);\
  837. \fi0                 exit(3);\
  838. \fi0         \}\
  839. \fi0 \
  840.         /* Pass the message to old exception handler, if necessary. */\
  841. \fi0         if (pass_on == TRUE) \{    \
  842. \fi0             imsg->msg_remote_port = port_p->old_exc_port;\
  843. \fi0             imsg->msg_local_port = port_p->clear_port;\
  844. \fi0             r = msg_send(imsg, MSG_OPTION_NONE, 0);\
  845. \fi0             if (r != SEND_SUCCESS) \{\
  846. \fi0                 mach_error("msg_send to old_exc_port", r);\
  847. \fi0                 exit(4);\
  848. \fi0             \}\
  849. \fi0         \}\
  850. \fi0     \}\
  851. \fi0 \}\
  852. \fi0 \
  853. /* \
  854. \fi0  * catch_exception_raise() is called by exc_server().  The only\
  855. \fi0  * exception it can handle is EXC_SOFTWARE.  \
  856. \fi0  */\
  857. \fi0 kern_return_t catch_exception_raise(port_t exception_port, \
  858. \fi0     port_t thread, port_t task, int exception, int code, int subcode)\
  859. \fi0 \{\
  860. \fi0     if ((exception == EXC_SOFTWARE) && (code == 0x20000)) \{\
  861. \fi0         /* Handle the exception so that the program can continue. */\
  862. \fi0         mutex_lock(printing);\
  863. \fi0         printf("Handling the exception\\n");\
  864. \fi0         mutex_unlock(printing);\
  865. \fi0         return KERN_SUCCESS;\
  866. \fi0     \}\
  867. \fi0     else \{ /* Pass the exception on to the old port. */\
  868. \fi0         pass_on = TRUE;\
  869. \fi0         mach_NeXT_exception("Forwarding exception", exception, \
  870. \fi0             code, subcode);\
  871. \fi0         return KERN_FAILURE;  /* Couldn\'27t handle this exception. */\
  872. \fi0     \}\
  873. \fi0 \}\
  874. \fi0 \
  875. main()\
  876. \fi0 \{\
  877. \fi0     int             i;\
  878. \fi0     kern_return_t   r;\
  879. \fi0     ports_t         ports;\
  880. \fi0     \
  881. \fi0     printing = mutex_alloc();\
  882. \fi0 \
  883.     /* Save the old exception port for this task. */\
  884. \fi0     r = task_get_exception_port(task_self(), &(ports.old_exc_port));\
  885. \fi0     if (r != KERN_SUCCESS) \{\
  886. \fi0         mach_error("task_get_exception_port", r);\
  887. \fi0         exit(1);\
  888. \fi0     \} \
  889. \fi0 \
  890.     /* Create a new exception port for this task. */\
  891. \fi0     r = port_allocate(task_self(), &(ports.exc_port));\
  892. \fi0     if (r != KERN_SUCCESS) \{\
  893. \fi0         mach_error("port_allocate 0", r);\
  894. \fi0         exit(1);\
  895. \fi0     \}\
  896. \fi0     r = task_set_exception_port(task_self(), (ports.exc_port));\
  897. \fi0     if (r != KERN_SUCCESS) \{\
  898. \fi0         mach_error("task_set_exception_port", r);\
  899. \fi0         exit(1);\
  900. \fi0     \}\
  901. \fi0 \
  902.     /* Fork the thread that listens to the exception port. */\
  903. \fi0     cthread_detach(cthread_fork((cthread_fn_t)exc_thread,\
  904. \fi0         (any_t)&ports));\
  905. \fi0     /* Raise the exception. */\
  906. \fi0     ports.clear_port = thread_self();\
  907. \fi0     r = exception_raise(ports.exc_port, thread_reply(),\
  908. \fi0         ports.clear_port, task_self(), EXC_SOFTWARE, 0x20000, 6);\
  909. \fi0 \
  910.     if (r != KERN_SUCCESS) \
  911. \fi0         mach_error("catch_exception_raise didn\'27t handle exception",\
  912. \fi0             r);\
  913. \fi0     else \{\
  914. \fi0         mutex_lock(printing);\
  915. \fi0         printf("Successfully called exception_raise\\n");\
  916. \fi0         mutex_unlock(printing);\
  917. \fi0     \}\
  918. \fi0 \}\
  919. \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  920. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b exception_raise()\b0 , \b mach_NeXT_exception()\
  921. \fs20 \
  922. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  923. \fs28 exception_raise()\
  924. \fs20 \
  925. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  926. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Cause an exception to occur \
  927. \fs28 \
  928. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  929. \fi0 #import <mach/exception.h>\
  930. \fs10 \
  931. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b exception_raise(\b0 port_t \i exception_port\i0 , port_t \i clear_port\i0 , port_t \i thread\i0 , port_t \i task\i0 , int \i exception\i0 , int \i code\i0 , int \i subcode\b \i0 )\
  932. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  933. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i exception_port\i0 :  The exception port of the affected thread.  (If the thread doesn\'27t have its own exception port, then this should be the exception port of the task.)\
  934. \fs20 \
  935. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i clear_port\i0 :  The port to which a reply message should be sent from the exception handler.  If you don\'27t care to see the reply, you can use \b thread_reply()\b0 .\
  936. \fs20 \
  937. \fs28 \i thread\i0 :  The thread in which the exception condition occurred.  If the exception isn\'27t thread-specific, then specify THREAD_NULL.\
  938. \fs20 \
  939. \fs28 \i task\i0 :  The task in which the exception condition occurred.\
  940. \fs20 \
  941. \fs28 \i exception\i0 :  The type of exception that occurred; for example, EXC_SOFTWARE.  Values for this variable are defined in the header file \b mach/exception.h\b0 .\
  942. \fs20 \
  943. \fs28 \i code\i0 :  The exception code.  The meaning of this code depends on the value of \i exception\i0 .\
  944. \fs20 \
  945. \fs28 \i subcode\i0 :  The exception subcode.  The meaning of this subcode depends on the values of \i exception\i0  and \i code\i0 .\
  946. \fs20 \
  947. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  948. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 This function causes an exception message to be sent to \i exception_port\i0 , which results in a call to the exception handler.  Usually this function is used along with a user-defined exception handler.  (See \b exc_server()\b0  and \b mach_NeXT_exception()\b0  for more information on user-defined exception handlers.)\
  949. \fs20 \
  950. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 You can obtain \i exception_port\i0  by calling \b thread_get_exception_port()\b0  or (if no thread exception port exists or the exception affects the whole task) \b task_get_exception_port()\b0 .\
  951. \fs20 \
  952. \fs28 If you\'27re defining your own type of exception, you must have \i exception\i0  equal to EXC_SOFTWARE and \i code\i0  equal to or greater than 0x20000.\
  953. \fs20 \
  954. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  955. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 /* Raise the exception. */\
  956. \fi0 r = exception_raise(ports.exc_port, thread_reply(), thread_self(),\
  957. \fi0     task_self(), EXC_SOFTWARE, 0x20000, 6);\
  958. \fi0 if (r != KERN_SUCCESS)\
  959. \fi0     mach_error("catch_exception_raise didn\'27t handle exception", r);\
  960. \fi0 else \{\
  961. \fi0     /* Use mutex so only one thread at a time can call printf. */\
  962. \fi0     mutex_lock(printing);\
  963. \fi0     printf("Successfully called exception_raise\\n");    \
  964. \fi0     mutex_unlock(printing);\
  965. \fi0 \}\
  966. \s25 \fi-2015 \f1 \fs28 \fs28 \
  967. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  968. \fs20 \
  969. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_FAILURE:  The exception handler didn\'27t successfully deal with the exception.\
  970. \fs20 \
  971. \fs28 KERN_INVALID_ARGUMENT:  One of the arguments wasn\'27t valid.\
  972. \fs20 \
  973. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  974. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b exc_server()\b0 , \b mach_NeXT_exception()\b0 , \b task_get_exception_port()\b0 , \b thread_get_exception_port()\
  975. \fs20 \
  976. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  977. \fs28 host_info()\
  978. \fs20 \
  979. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  980. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get information about a host\
  981. \fs28 \
  982. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  983. \fs10 \
  984. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b host_info(\b0 host_t \i host\i0 , int \i flavor\i0 , host_info_t \i host_info\i0 , unsigned int *\i host_info_count\b \i0 )\
  985. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  986. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i host\i0 :  The host for which information is to be obtained.\
  987. \fs20 \
  988. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i flavor\i0 :  The type of statistics to be returned.  Currently HOST_BASIC_INFO, HOST_PROCESSOR_SLOTS, and HOST_SCHED_INFO are implemented.\
  989. \fs20 \
  990. \fs28 \i host_info\i0 :  Returns statistics about \i host\i0 .\
  991. \fs20 \
  992. \fs28 \i host_info_count\i0 :  The number of integers in the info structure; returns the number of integers that Mach tried to fill the info structure with.  For HOST_BASIC_INFO, you should set \i host_info_count\i0  to HOST_BASIC_INFO_COUNT.  For HOST_PROCESSOR_SLOTS, you should set it to the maximum number of CPUs (returned by HOST_BASIC_INFO).  For HOST_SCHED_INFO, set it to HOST_SCHED_INFO_COUNT.\
  993. \fs20 \
  994. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  995. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 Returns the selected information array for a host, as specified by \i flavor\i0 .  The \i host_info\i0  argument is an array of integers that\'27s supplied by the caller and returned filled with specified information.  The \i host_info_count\i0  argument is supplied by the caller as the maximum number of integers in \i host_info\i0  (which can be larger than the space required for the information).  On return, it contains the actual number of integers in \i host_info\i0 .  \
  996. \fs20 \
  997. \fs28 \pard \s48 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Warning:  \b0 \fs28 \f1 This replaces the old \b host_info()\b0  call.  It isn\'27t backwards compatible.\
  998. \fs20 \
  999. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Basic information is defined by HOST_BASIC_INFO.  Its size is defined by HOST_BASIC_INFO_COUNT.  Possible values of the \b cpu_type\b0  and \b cpu_subtype\b0  fields are defined in the header file \b mach/machine.h\b0 , which is included in \b mach/mach.h\b0 .\
  1000. \fs20 \
  1001. \fs28 \pard \s12 \li2494 \fi0 \ri1007 \ql \f2 \fs24 struct host_basic_info \{\
  1002. \fi0     int           max_cpus;     /* maximum possible cpus for\
  1003. \fi0                                  * which kernel is configured */\
  1004. \fi0     int           avail_cpus;   /* number of cpus now available */\
  1005. \fi0     vm_size_t     memory_size;  /* size of memory in bytes */\
  1006. \fi0     cpu_type_t    cpu_type;     /* cpu type */\
  1007. \fi0     cpu_subtype_t cpu_subtype;  /* cpu subtype */\
  1008. \fi0 \};\
  1009. \fi0 typedef struct host_basic_info *host_basic_info_t;\
  1010. \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \f1 \fs28 \fs20 \
  1011. \fs28 Processor slots of the active (available) processors are defined by HOST_PROCESSOR_SLOTS.  The size of this information should be obtained from the \b max_cpus\b0  field of the structure returned by HOST_BASIC_INFO.  HOST_PROCESSOR_SLOTS returns an array of integers, each of which is the slot number of a CPU.\
  1012. \fs20 \
  1013. \fs28 Additional information of interest to schedulers is defined by HOST_SCHED_INFO.  The size of this information is defined by HOST_SCHED_INFO_COUNT.\
  1014. \fs20 \
  1015. \fs28 \pard \s12 \li2494 \fi0 \ri1007 \ql \f2 \fs24 struct host_sched_info \{\
  1016. \fi0     int  min_timeout;  /* minimum timeout in milliseconds */\
  1017. \fi0     int  min_quantum;  /* minimum quantum in milliseconds */\
  1018. \fi0 \};\
  1019. \fi0 \
  1020. \fi0 typedef struct host_sched_info *host_sched_info_t\
  1021. \pard \s19 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  1022. \fs28 \f0 \b \fs20     EXAMPLE    \b0 \fs28 \f1 An example of using HOST_BASIC_INFO:\
  1023. \fs20 \
  1024. \fs28 \pard \s12 \li2494 \fi0 \ri1007 \ql \f2 \fs24 kern_return_t           ret;\
  1025. \fi0 struct host_basic_info  basic_info;\
  1026. \fi0 unsigned int            count=HOST_BASIC_INFO_COUNT;\
  1027. \fi0 \
  1028. \fi0 ret=host_info(host_self(), HOST_BASIC_INFO, \
  1029. \fi0     (host_info_t)&basic_info, &count);\
  1030. \fi0 if (ret != KERN_SUCCESS)\
  1031. \fi0     mach_error("host_info() call failed", ret);\
  1032. \fi0 else printf("This system has %d bytes of RAM.\\n", \
  1033. \fi0     basic_info.memory_size);\
  1034. \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \f1 \fs28 \fs20 \
  1035. \fs28 An example of using HOST_PROCESSOR_SLOTS (you also need to include the HOST_BASIC_INFO code above so you can get \b max_cpus\b0 ):\
  1036. \fs20 \
  1037. \fs28 \pard \s12 \li2494 \fi0 \ri1007 \ql \f2 \fs24 host_info_t  slots;\
  1038. \fi0 unsigned int cpu_count, i;\
  1039. \fi0 \
  1040. \fi0 cpu_count=basic_info.max_cpus;\
  1041. \fi0 slots=(host_info_t)malloc(cpu_count*sizeof(int));\
  1042. \fi0 ret=host_info(host_self(), HOST_PROCESSOR_SLOTS, slots, \
  1043. \fi0     &cpu_count);\
  1044. \fi0 if (ret!=KERN_SUCCESS)\
  1045. \fi0     mach_error("PROCESSOR host_info() call failed", ret);\
  1046. \fi0 else for (i=0; i<cpu_count; i++) \
  1047. \fi0     printf("CPU %d is in slot %d.\\n", i, *slots++);\
  1048. \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \f1 \fs28 \fs20 \
  1049. \fs28 An example of using HOST_SCHED_INFO:  \
  1050. \fs20 \
  1051. \fs28 \s12 \li2494 \fi-378 \fi0 \f2 \fs24 kern_return_t           ret;\
  1052. \fi0 struct host_sched_info  sched_info;\
  1053. \fi0 unsigned int            sched_count=HOST_SCHED_INFO_COUNT;\
  1054. \fi0 \
  1055. \fi0 ret=host_info(host_self(), HOST_SCHED_INFO, \
  1056. \fi0     (host_info_t)&sched_info, &sched_count);\
  1057. \fi0 if (ret != KERN_SUCCESS)\
  1058. \fi0     mach_error("SCHED host_info() call failed", ret);\
  1059. \fi0 else\
  1060. \fi0     printf("The minimum quantum is %d milliseconds.\\n",\
  1061. \fi0         sched_info.min_quantum);\
  1062. \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  1063. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  1064. \fs20 \
  1065. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i host\i0  is not a host, \i flavor\i0  is not recognized, or (for HOST_PROCESSOR_SLOTS) *\i count\i0  is less than \b max_cpus\b0 .\
  1066. \fs20 \
  1067. \fs28 KERN_FAILURE:  *\i count\i0  is less than HOST_BASIC_INFO_COUNT (when \i flavor\i0  is HOST_BASIC_INFO) or HOST_SCHED_INFO_COUNT (for HOST_SCHED_INFO).\
  1068. \fs20 \
  1069. \fs28 MIG_ARRAY_TOO_LARGE:  Returned info array is too large for \i host_info\i0 .  The \i host_info\i0  argument is filled as much as possible, and \i host_info_count\i0  is set to the number of elements that would be returned if there were enough room.\
  1070. \fs20 \
  1071. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1072. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b host_kernel_version()\b0 , \b host_processors()\b0 , \b processor_info()\
  1073. \fs20 \
  1074. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  1075. \fs28 host_kernel_version()\
  1076. \fs20 \
  1077. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  1078. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get kernel version information\
  1079. \fs28 \
  1080. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  1081. \fs10 \
  1082. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b host_kernel_version(\b0 host_t \i host\i0 , kernel_version_t \i version\b \i0 )\
  1083. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  1084. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i host\i0 :  The host for which information is being requested.\
  1085. \fs20 \
  1086. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i version\i0 :  Returns a character string describing the kernel version executing on \i host\i0 .\
  1087. \fs20 \
  1088. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1089. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 This function returns the version string compiled into \i host\i0 \'27s kernel\b  \b0 at the time it was built.  If you don\'27t use the \b kernel_version_t\b0  declaration, then you should allocate KERNEL_VERSION_MAX bytes for the version string.\
  1090. \fs20 \
  1091. \fs28 \s18 \f2 \fs24 \fs10 \
  1092. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 kern_return_t       ret;\
  1093. \fi0 kernel_version_t    string;\
  1094. \fi0 \
  1095. \fi0 ret=host_kernel_version(host_self(), string);\
  1096. \fi0 if (ret != KERN_SUCCESS)\
  1097. \fi0     mach_error("host_kernel_version() call failed", ret);\
  1098. \fi0 else\
  1099. \fi0     printf("Version string:  %s\\n", string);\
  1100. \s25 \fi-2015 \f1 \fs28 \fs28 \
  1101. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  1102. \fs20 \
  1103. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i host\i0  was not a host.\
  1104. \fs20 \
  1105. \fs28 KERN_INVALID_ADDRESS:  \i version\i0  points to inaccessible memory.\
  1106. \fs20 \
  1107. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1108. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b host_info()\b0 , \b host_processors()\b0 , \b processor_info()\
  1109. \fs20 \
  1110. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  1111. \fs28 host_processor_set_priv() \
  1112. \fs20 \
  1113. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  1114. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get the privileged port of a processor set\
  1115. \fs28 \
  1116. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  1117. \fs10 \
  1118. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b host_processor_set_priv(\b0 host_priv_t \i host_priv\i0 , processor_set_t \i processor_set_name\i0 , processor_set_t *\i processor_set\b \i0 )\
  1119. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  1120. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i host_priv\i0 :  The privileged host port for the desired host.\
  1121. \fs20 \
  1122. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i processor_set_name\i0 :  The name port of the processor set.\
  1123. \fs20 \
  1124. \fs28 \i processor_set\i0 :  Returns the privileged port of the processor set.\
  1125. \fs20 \
  1126. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1127. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 This function returns send rights to the privileged port for the specified processor set.  This port is used in calls that can affect other threads or tasks.  For example, \b processor_set_tasks()\b0  requires the privileged port because it returns the port of every task on the system.  \
  1128. \fs20 \
  1129. \fs28 \s18 \f2 \fs24 \fs10 \
  1130. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 kern_return_t    error;\
  1131. \fi0 processor_set_t  processor_set;\
  1132. \fi0 processor_set_t  default_set;\
  1133. \pard \s14 \li2116 \fi0 \ri503 \ql \
  1134. error=processor_set_default(host_self(), &default_set);\
  1135. \fi0 if (error != KERN_SUCCESS)\
  1136. \fi0     mach_error("Call to processor_set_default failed", error);\
  1137. \fi0 \
  1138. error=host_processor_set_priv(host_priv_self(), default_set,\
  1139. \fi0     &processor_set);\
  1140. \fi0 if (error != KERN_SUCCESS)\
  1141. \fi0     mach_error("Call to host_processor_set_priv failed; make sure\
  1142. \fi0         you\'27re superuser", error);\
  1143. \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  1144. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  1145. \fs20 \
  1146. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i host_priv\i0  was not a privileged host port, or \i processor_set_name\i0  didn\'27t name a valid processor set.\
  1147. \fs20 \
  1148. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 \fs60 \
  1149. \fs28 host_processor_sets()\
  1150. \fs20 \
  1151. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  1152. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get the name ports of all processor sets on a host\
  1153. \fs28 \
  1154. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  1155. \fs10 \
  1156. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b host_processor_sets(\b0 host_t \i host\i0 , processor_set_name_array_t *\i processor_set_list\i0 , unsigned int *\i processor_set_count\b \i0 )\
  1157. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  1158. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i host\i0 :  The host port for the desired host.  \
  1159. \fs20 \
  1160. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i processor_set_list\i0 :  Returns an array of processor sets currently existing on \i host\i0 ; no particular ordering is guaranteed.\
  1161. \fs20 \
  1162. \fs28 \i processor_set_ count\i0 :  Returns the number of processor sets in the \i processor_set_list\i0 .\
  1163. \fs20 \
  1164. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1165. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 This function returns send rights to the name port for each processor set currently assigned to \i host\i0 .  The \b host_processor_set_priv()\b0  function can be used to obtain the privileged ports from these if desired.  The \i processor_set_list\i0  argument is an array that is created as a result of this call.  You should call \b vm_deallocate()\b0  on this array when the data is no longer needed.  \
  1166. \fs20 \
  1167. \fs28 \pard \s37 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Note:  \b0 \fs28 \f1 In single-processor systems, you can get the same information by calling \b processor_set_default()\b0 .\
  1168. \fs20 \
  1169. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  1170. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 kern_return_t               ret;\
  1171. \fi0 processor_set_name_array_t  list;\
  1172. \fi0 unsigned int                count;\
  1173. \fi0 \
  1174. \fi0 ret=host_processor_sets(host_self(), &list, &count);\
  1175. \fi0 if (ret!=KERN_SUCCESS)\
  1176. \fi0     mach_error("error calling host_processor_sets", ret);\
  1177. \fi0 else \{\
  1178. \fi0     /* . . . */\
  1179. \fi0     ret=vm_deallocate(task_self(), (vm_address_t)list,\
  1180. \fi0         sizeof(list)*count); \
  1181. \fi0     if (ret!=KERN_SUCCESS)\
  1182. \fi0         mach_error("error calling vm_deallocate", ret); \
  1183. \fi0 \}\
  1184. \s25 \fi-2015 \f1 \fs28 \fs28 \
  1185. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  1186. \fs20 \
  1187. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i host\i0  is not a host.\
  1188. \fs20 \
  1189. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1190. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b host_processor_set_priv()\b0 , \b processor_set_create()\b0 , \b processor_set_tasks()\b0 , \b processor_set_threads()\b0 , \b processor_set_default()\
  1191. \fs20 \
  1192. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  1193. \fs28 host_processors()\
  1194. \fs20 \
  1195. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  1196. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get the processor ports for a host\
  1197. \fs28 \
  1198. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  1199. \fs10 \
  1200. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b host_processors(\b0 host_priv_t \i host_priv\i0 , processor_array_t *\i processor_list\i0 , unsigned int *\i processor_count\b \i0 )\
  1201. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  1202. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i host_priv\i0 :  Privileged host port for the desired host.\
  1203. \fs20 \
  1204. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i processor_list\i0 :  Returns the processors existing on \i host_priv\i0 ; no particular ordering is guaranteed.\
  1205. \fs20 \
  1206. \fs28 \i processor_count\i0 :  Returns the number of processors in \i processor_list\i0 .\
  1207. \fs20 \
  1208. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1209. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 \b host_processors()\b0  gets send rights to the processor port for each processor existing on \i host_priv\i0 .  The \i processor_list\i0  argument is an array that is created as a result of this call.  The caller may wish to call \b vm_deallocate()\b0  on this array when the data is no longer needed.  \
  1210. \fs20 \
  1211. \fs28 \s18 \f2 \fs24 \fs10 \
  1212. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 kern_return_t      error;\
  1213. \fi0 processor_array_t  list;\
  1214. \fi0 unsigned int       count;\
  1215. \fi0 \
  1216. \fi0 error=host_processors(host_priv_self(), &list, &count);\
  1217. \fi0 if (error!=KERN_SUCCESS)\{\
  1218. \fi0     mach_error("error calling host_processors", error);\
  1219. \fi0     exit(1);\
  1220. \fi0 \}\
  1221. \fi0 /* . . . */\
  1222. \fi0 vm_deallocate(task_self(), (vm_address_t)list, sizeof(list)*count);\
  1223. \fi0 if (error!=KERN_SUCCESS)\
  1224. \fi0     mach_error("Trouble freeing list", error);\
  1225. \s25 \fi-2015 \f1 \fs28 \fs28 \
  1226. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  1227. \fs20 \
  1228. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i host_priv\i0  is not a privileged host port.\
  1229. \fs20 \
  1230. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1231. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b processor_info()\b0 , \b processor_start()\b0 , \b processor_exit()\b0 , \b processor_control()\
  1232. \fs20 \
  1233. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  1234. \fs28 host_self(), host_priv_self()\
  1235. \fs20 \
  1236. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  1237. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get the host port for this host\
  1238. \fs28 \
  1239. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  1240. \fs10 \
  1241. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 host_t \b host_self(\b0 void\b )\
  1242. \b0 host_priv_t \b host_priv_self(\b0 void\b )\
  1243. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  1244. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The \b host_self()\b0  function returns send rights to the host port for the host on which the call is executed.  This port can be used only to obtain information about the host, not to control the host.\
  1245. \fs20 \
  1246. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The \b host_priv_self()\b0  function returns send rights to the privileged host port for the host on which the call is executed.  This port is used to control physical resources on that host and is only available to privileged tasks.  PORT_NULL is returned if the invoker is not the UNIX superuser.\
  1247. \fs20 \
  1248. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  1249. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 /* Get the privileged port for the default processor set. */\
  1250. \fi0 error=processor_set_default(host_self(), &default_set);\
  1251. \fi0 if (error!=KERN_SUCCESS) \{\
  1252. \fi0     mach_error("Error calling processor_set_default()", error);\
  1253. \fi0     exit(1);\
  1254. \fi0 \}\
  1255. \pard \s14 \li2116 \fi0 \ri503 \ql \
  1256. error=host_processor_set_priv(host_priv_self(), default_set,\
  1257. \fi0     &default_set_priv);\
  1258. \fi0 if (error!=KERN_SUCCESS) \{\
  1259. \fi0     mach_error("Call to host_processor_set_priv() failed", error);\
  1260. \fi0     exit(1);\
  1261. \fi0 \}\
  1262. \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  1263. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b host_processors()\b0 , \b host_info()\b0 , \b host_kernel_version()\
  1264. \fs20 \
  1265. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  1266. \fs28 mach_error(), mach_error_string()\
  1267. \fs20 \
  1268. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  1269. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Display or get a Mach error string\
  1270. \fs28 \
  1271. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  1272. \fi0 #import <mach/mach_error.h>\
  1273. \fs10 \
  1274. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 void \b mach_error(\b0 char *\i string\i0 , kern_return_t \i error\b \i0 )\
  1275. \b0 char *\b mach_error_string(\b0 kern_return_t\i  error\b \i0 )\
  1276. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  1277. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i string\i0 :  The string you want displayed before the Mach error string.\
  1278. \fs20 \
  1279. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i error\i0 :  The error value for which you want an error string.\
  1280. \fs20 \
  1281. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1282. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b mach_error()\b0  displays a message on \b stderr\b0 .  The message contains the string specified by \i string\i0 , the string returned by \b mach_error_string()\b0 , and the actual error value (\i error\i0 ).  Since\b  mach_error()\b0  isn\'27t thread-safe, you might want to protect it with a mutex if you call it in a multiple-thread task.\
  1283. \fs20 \
  1284. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The function \b mach_error_string()\b0  returns the string associated with \i error\i0 .\
  1285. \fs20 \
  1286. \fs28 Note that because the error value specified by \i error\i0  is of type \b kern_return_t\b0 , these functions work only with Mach functions.\
  1287. \fs20 \
  1288. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  1289. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 mutex_t        printing;\
  1290. \fi0 \
  1291. \fi0 main()\
  1292. \fi0 \{\
  1293. \fi0     kern_return_t  error;\
  1294. \fi0     port_t         result;\
  1295. \fi0 \
  1296. \fi0     printing = mutex_alloc();\
  1297. \fi0 \
  1298. \fi0     /* . . . */\
  1299. \fi0     if ((error=port_allocate(task_self(), &result)) != KERN_SUCCESS) \{\
  1300. \fi0         mutex_lock(printing);\
  1301. \fi0         mach_error("Error calling port_allocate", error); \
  1302. \fi0         mutex_unlock(printing);\
  1303. \fi0         exit(1);\
  1304. \fi0     \}\
  1305. \fi0     /* . . . */\
  1306. \fi0 \}\
  1307. \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 \fs80 \
  1308. \fs28 mach_NeXT_exception(), mach_NeXT_exception_string()\
  1309. \fs20 \
  1310. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  1311. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Display or get a Mach exception string\
  1312. \fs28 \
  1313. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  1314. \fs10 \
  1315. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 void \b mach_NeXT_exception(\b0 char *\i string\i0 , int \i exception\i0 , int \i code\i0 , int \i subcode\b \i0 )\
  1316. \b0 char *\b mach_NeXT_exception_string(\b0 int \i exception\i0 , int \i code\i0 , int \i subcode\b \i0 )\
  1317. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  1318. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i string\i0 :  The string you want displayed before the Mach exception string.\
  1319. \fs20 \
  1320. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i exception\i0 :  The exception value for which you want a string.\
  1321. \fs20 \
  1322. \fs28 \i code\i0 :  The exception code.  How this is used depends on the value of \i exception\i0 .\
  1323. \fs20 \
  1324. \fs28 \i subcode\i0 :  The exception subcode.  How this is used depends on the value of \i exception\i0 .\
  1325. \fs20 \
  1326. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1327. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b mach_NeXT_exception()\b0  displays a message on \b stderr\b0 .  The message contains the string specified by \i string\i0 , then the string returned by \b mach_NeXT_exception_string()\b0 , and then the values of \i exception\i0 , \i code\i0 , and \i subcode\i0 .  Since\b  mach_NeXT_exception()\b0  isn\'27t thread-safe, you might want to protect it with a mutex if you call it in a multiple-thread task.\
  1328. \fs20 \
  1329. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The function \b mach_NeXT_exception_string()\b0  returns the string associated with \i exception\i0 , \i code\i0 , and \i subcode\i0 .\
  1330. \fs20 \
  1331. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  1332. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 /* \
  1333. \fi0  * catch_exception_raise() is called by exc_server().  The only\
  1334. \fi0  * exception it can handle is EXC_SOFTWARE.  \
  1335. \fi0  */\
  1336. \fi0 kern_return_t catch_exception_raise(port_t exception_port, \
  1337. \fi0     port_t thread, port_t task, int exception, int code, int subcode)\
  1338. \fi0 \{\
  1339. \fi0     if ((exception == EXC_SOFTWARE) && (code == 0x20000)) \{\
  1340. \fi0         /* Handle the exception so that the program can continue. */\
  1341. \fi0         mutex_lock(printing);\
  1342. \fi0         printf("Handling the exception\\n");\
  1343. \fi0         mutex_unlock(printing);\
  1344. \fi0         return KERN_SUCCESS;\
  1345. \fi0     \}\
  1346. \fi0     else \{ /* Pass the exception on to the old port. */\
  1347. \fi0         pass_on = TRUE;\
  1348. \fi0         mach_NeXT_exception("Forwarding exception", exception, \
  1349. \fi0             code, subcode);\
  1350. \fi0         return KERN_FAILURE;  /* Couldn\'27t handle this exception. */\
  1351. \fi0     \}\
  1352. \fi0 \}\
  1353. \s26 \fi-2015 \f1 \fs28 \fs28 \
  1354. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b exception_raise()\b0 , \b exc_server()\
  1355. \fs20 \
  1356. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  1357. \fs28 map_fd()\
  1358. \fs20 \
  1359. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  1360. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Map a file into virtual memory\
  1361. \fs28 \
  1362. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  1363. \fs10 \
  1364. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b map_fd(\b0 int \i fd\i0 , vm_offset_t \i offset\i0 , vm_offset_t *\i address\i0 , boolean_t \i find_space\i0 , vm_size_t \i size\b \i0 )\
  1365. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  1366. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i fd\i0 :  An open UNIX file descriptor for the file that\'27s to be mapped.\
  1367. \fs20 \
  1368. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i offset\i0 :  The byte offset within the file, at which mapping is to begin.\
  1369. \fs20 \
  1370. \fs28 \i address\i0 :  A pointer to an address in the calling process at which the mapped file should start.  This address, unlike the offset, must be page-aligned.\
  1371. \fs20 \
  1372. \fs28 \i find_space\i0 :  If true, the kernel will select an unused address range at which to map the file and return its value in \i address\i0 .\
  1373. \fs20 \
  1374. \fs28 \i size\i0 :  The number of bytes to be mapped.\
  1375. \fs20 \
  1376. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1377. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b map_fd()\b0  is a UNIX extension that\'27s technically not part of Mach.  This function causes \i size\i0  bytes of data starting at \i offset\i0  in the file specified by \i fd\i0  to be mapped into the virtual memory at the address specified by \i address.  \i0 If \i find_space\i0  is true, the input value of \i address\i0  can be null, and the kernel will find an unused piece of virtual memory to use.  (You should free this space with \b vm_deallocate()\b0  when you no longer need it.)  If you provide a value for \i address\i0 , it must be page-aligned and at least \i size\i0  bytes long.  The sum of \i offset\i0  and \i size\i0  must not exceed the length of the file.\
  1378. \fs20 \
  1379. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Memory mapping doesn\'27t cause I/O to take place.  When specific pages are first referenced, they cause page faults that bring in the data.  The mapped memory is copy-on-write.  Modified data is returned to the file only by a \b write()\b0  call.\
  1380. \fs20 \
  1381. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  1382. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 kern_return_t r;\
  1383. \fi0 int           fd;\
  1384. \fi0 char         *memfile, *filename = "/tmp/myfile";\
  1385. \fi0 \
  1386. \fi0 /* Open the file. */\
  1387. \fi0 fd = open(filename, O_RDONLY);\
  1388. \fi0 \
  1389. \fi0 /* Map part of it into memory. */\
  1390. \fi0 r = map_fd(fd, (vm_offset_t)0, &(vm_offset_t)memfile, TRUE,\
  1391. \fi0     (vm_size_t)5);\
  1392. \fi0 if (r != KERN_SUCCESS)\
  1393. \fi0     mach_error("Error calling map_fd()", r);\
  1394. \fi0 else\
  1395. \fi0     printf("Second character in %s is:  %c\\n", filename, memfile[1]);\
  1396. \s25 \fi-2015 \f1 \fs28 \fs28 \
  1397. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The data was mapped successfully.\
  1398. \fs20 \
  1399. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ADDRESS:  \i address\i0  wasn\'27t valid.\
  1400. \fs20 \
  1401. \fs28 KERN_INVALID_ARGUMENT:  An invalid argument was passed.\
  1402. \fs20 \
  1403. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 \fs60 \
  1404. \fs28 msg_receive()\
  1405. \fs20 \
  1406. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  1407. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Receive a message\
  1408. \fs28 \
  1409. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  1410. \fi0 #import <mach/message.h>\
  1411. \fs10 \
  1412. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 msg_return_t \b msg_receive(\b0 msg_header_t *\i header\i0 , msg_option_t \i option\i0 , msg_timeout_t \i timeout\b \i0 )\
  1413. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  1414. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i header\i0 :  The address of a buffer in which the message is to be received.  Two fields of the message header must be set before the call is made:  \b msg_local_port\b0  must be set to the value of the port from which the message is to be received, and \b msg_size\b0  must be set to the maximum size of the message that may be received.  This maximum size must be less than or equal to the size of the buffer.\
  1415. \fs20 \
  1416. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i option\i0 :  The failure conditions under which \b msg_receive()\b0  should terminate.  The value of this argument is a combination (using the bitwise OR operator) of the following options.  Unless one of these values is explicitly specified, \b msg_receive()\b0  does not return until a message has been received.\
  1417. \fs20 \
  1418. \fs28 \pard \s5 \li2494 \fi0 \ri1007 \ql \tx2872 \tx3250 \tx3642 RCV_TIMEOUT:  Specifies that \b msg_receive()\b0  should return when the specified timeout elapses if a message has not arrived by that time; if not specified, the timeout will be ignored (that is, it will be infinite).\
  1419. \fs20 \
  1420. \fs28 RCV_INTERRUPT:  Specifies that \b msg_receive()\b0  should return when a software interrupt occurs in this thread.\
  1421. \fs20 \
  1422. \fs28 RCV_LARGE:  Specifies that \b msg_receive()\b0  should return without dequeuing a message if the next message in the queue is larger than \i header\b \i0 .msg_size\b0 .  (Normally, a message that is too large is dequeued and lost.)  You can use this option to dynamically determine how large your message buffer must be.\
  1423. \fs20 \
  1424. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Use MSG_OPTION_NONE to specify that none of the above options is desired.\
  1425. \fs20 \
  1426. \fs28 \i timeout\i0 :  If RCV_TIMEOUT is specified in \i option\i0 , then \i timeout\i0  is the maximum time in milliseconds to wait for a message before giving up.\
  1427. \fs20 \
  1428. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1429. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b msg_receive()\b0  retrieves the next message from the port or port set specified in the \b msg_local_port\b0  field of \i header\i0 .  If a port is specified, the port must\i  \i0 not be a member of a port set.  \
  1430. \fs20 \
  1431. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 If a port set is specified, then \b msg_receive()\b0  will retrieve messages sent to any of the set\'27s member ports.  Mach sets the \b msg_local_port\b0  field to the specific port on which the message was found.  It\'27s not an error for the port set to have no members, or for members to be added and removed from a port set while a \b msg_receive()\b0  on the port set is in progress.  \
  1432. \fs20 \
  1433. \fs28 The message consists of its header, followed by a variable amount of data; the message header supplied to \b msg_receive()\b0  must specify (in \b msg_size\b0 ) the maximum size of the message that can be received into the buffer provided.\
  1434. \fs20 \
  1435. \fs28 If no messages are present on the port(s) in question, \b msg_receive()\b0  will wait until a message arrives, or until one of the specified termination conditions is met (see the description of the \i option\i0  argument for this function).\
  1436. \fs20 \
  1437. \fs28 If the message is successfully received, then \b msg_receive()\b0  sets the \b msg_size\b0  field of the header to the size of the received message.  If the RCV_LARGE option was set and \b msg_receive()\b0  returned RCV_TOO_LARGE, then the \b msg_size\b0  field is set to the size of the message that was too large.\
  1438. \fs20 \
  1439. \fs28 If the received message contains out-of-line data (that is, data for which the \b msg_type_inline\b0  attribute was specified as false), the data will be returned in a newly allocated region of memory; the message body will contain a pointer to that new region.  You should deallocate this memory when the data is no longer needed.  See the \b vm_allocate()\b0  call for a description of the state of newly allocated memory.\
  1440. \fs20 \
  1441. \fs28 See Chapter 2, \'aaUsing Mach Messages,\'ba for information on setting up messages and on writing Mach servers.\
  1442. \fs20 \
  1443. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  1444. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 msg_header_t   *imsg, header;\
  1445. \fi0 \
  1446. \fi0 /* Wait for messages. */\
  1447. \fi0 while (1) \{\
  1448. \fi0     /* Set up the message structure. */\
  1449. \fi0     header.msg_size = sizeof header;\
  1450. \fi0     header.msg_local_port = receive_port;\
  1451. \pard \s14 \li2116 \fi0 \ri503 \ql \
  1452.     /* Get the next message on the queue. */\
  1453. \fi0     r = msg_receive(&header, RCV_LARGE, 0);\
  1454. \fi0 \
  1455.     /* If the message is too big ... */\
  1456. \fi0     if (r==RCV_TOO_LARGE) \{\
  1457. \fi0         /* ... allocate a structure for it ... */\
  1458. \fi0         imsg = (msg_header_t *)malloc(header.msg_size);\
  1459. \fi0         /* ... initialize the structure ... */\
  1460. \fi0         imsg->msg_size = header.msg_size;\
  1461. \fi0         imsg->msg_local_port = receive_port;\
  1462. \fi0         /* ... and get the message. */\
  1463. \fi0         r = msg_receive(imsg, MSG_OPTION_NONE, 0);\
  1464. \fi0     \}\
  1465. \fi0     \
  1466. \fi0     if (r==RCV_SUCCESS) \{\
  1467. \fi0         /* Handle the message. */\
  1468. \fi0     \}\
  1469. \fi0     else \{ /* msg_receive() returned an error. */\
  1470. \fi0         mach_error("msg_receive", r);\
  1471. \fi0         exit(3);\
  1472. \fi0     \}\
  1473. \fi0 \}\
  1474. \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  1475. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 RCV_SUCCESS:  The message has been received.\
  1476. \fs20 \
  1477. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 RCV_INVALID_MEMORY:  The message specified was not writable by the calling task.\
  1478. \fs20 \
  1479. \fs28 RCV_INVALID_PORT:  An attempt was made to receive on a port to which the calling task does not have the proper access, or which was deallocated (see \b port_deallocate()\b0 ) while waiting for a message.\
  1480. \fs20 \
  1481. \fs28 RCV_TOO_LARGE:  The message header and body combined are larger than the size specified by \b msg_size\b0 .  Unless the RCV_LARGE option was set, the message has been dequeued and lost.  If the RCV_LARGE option was specified, then Mach sets \b msg_size\b0  to the size of the message that was too large and leaves the message at the head of the queue.\
  1482. \fs20 \
  1483. \fs28 RCV_NOT_ENOUGH_MEMORY:  The message to be received contains more out-of-line data than can be allocated in the receiving task.\
  1484. \fs20 \
  1485. \fs28 RCV_TIMED_OUT:  The message was not received after \i timeout\i0  milliseconds.\
  1486. \fs20 \
  1487. \fs28 RCV_INTERRUPTED:  A software interrupt occurred and the RCV_INTERRUPT option was specified.\
  1488. \fs20 \
  1489. \fs28 RCV_PORT_CHANGE:  The port specified was added to a port set during the duration of the \b msg_receive()\b0  call.\
  1490. \fs20 \
  1491. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 \fs60 \
  1492. \fs28 msg_rpc()\
  1493. \fs20 \
  1494. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  1495. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Send and receive a message\
  1496. \fs28 \
  1497. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  1498. \fi0 #import <mach/message.h>\
  1499. \fs10 \
  1500. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 msg_return_t \b msg_rpc(\b0 msg_header_t *\i header\i0 , msg_option_t \i option\i0 , msg_size_t \i rcv_size\i0 , msg_timeout_t \i send_timeout\i0 , msg_timeout_t \i rcv_timeout\b \i0 )\
  1501. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  1502. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i header\i0 :  Address of a message buffer that will be used for both \b msg_send()\b0  and \b msg_receive()\b0 .  This buffer contains a message header followed by the data for the message to be sent.  The \b msg_remote_port \b0 field specifies the port to which the message is to be sent.  The \b msg_local_port\b0  field specifies the port on which a message is then to be received; if this port is the special value PORT_DEFAULT, it gets replaced by the value PORT_NULL for the purposes of the \b msg_send()\b0  operation.\
  1503. \fs20 \
  1504. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i option\i0 :  A union of the \i option\i0  arguments for the send and receive (see \b msg_send()\b0  and \b msg_receive()\b0 ).\
  1505. \fs20 \
  1506. \fs28 \i rcv_size\i0 :  The maximum size allowed for the received message; this must be less than or equal to the size of the message buffer.  The \b msg_size\b0  field in the header specifies the size of the message to be sent.\
  1507. \fs20 \
  1508. \fs28 \i send_timeout\i0 ,\i  rcv_timeout\i0 :  The timeout values to be applied to the component operations.  These are used only if the option SEND_TIMEOUT or RCV_TIMEOUT is specified.\
  1509. \fs20 \
  1510. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1511. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b msg_rpc()\b0  is a hybrid call that performs a \b msg_send()\b0  followed by a \b msg_receive()\b0 , using the same message buffer.  Because of the order of the send and receive, this function is appropriate for clients of Mach servers.  However, the \b msg_rpc()\b0  call to a Mach server is usually performed by MiG-generated code, not by handwritten code.\
  1512. \fs20 \
  1513. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 See Chapter 2, \'aaUsing Mach Messages,\'ba for information on setting up messages and on writing Mach servers.\
  1514. \fs20 \
  1515. \fs28 \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1516. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 RPC_SUCCESS:  The message was successfully sent and a reply was received.\
  1517. \fs20 \
  1518. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Other possible values are the same as those for \b msg_send()\b0  and \b msg_receive()\b0 ; any error during the \b msg_send()\b0  portion will terminate the call.\
  1519. \fs20 \
  1520. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 \fs60 \
  1521. \fs28 msg_send()\
  1522. \fs20 \
  1523. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  1524. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Send a message\
  1525. \fs28 \
  1526. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  1527. \fi0 #import <mach/message.h>\
  1528. \fs10 \
  1529. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 msg_return_t \b msg_send(\b0 msg_header_t *\i header\i0 , msg_option_t \i option\i0 , msg_timeout_t \i timeout\b \i0 )\
  1530. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  1531. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i header\i0 :  The address of the message to be sent.  A message consists of a fixed-size header followed by a variable number of data descriptors and data items.  See the header file \b mach/message.h\b0  for a definition of the message structure.  \
  1532. \fs20 \
  1533. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i option\i0 :  The failure conditions under which \b msg_send()\b0  should terminate.  The value of this argument is a combination (using the bitwise OR operator) of the following options.  Unless one of these values is explicitly specified, \b msg_send()\b0  does not return until the message is successfully queued for the intended receiver.\
  1534. \fs20 \
  1535. \fs28 \pard \s5 \li2494 \fi0 \ri1007 \ql \tx2872 \tx3250 \tx3642 SEND_TIMEOUT:  Specifies that the \b msg_send()\b0  request should terminate after the timeout period has elapsed, even if the kernel has been unable to queue the message.\
  1536. \fs20 \
  1537. \fs28 SEND_NOTIFY:  Allows the sender to send exactly one message\i  \i0 without being suspended even if the destination port is full.  When that message can be posted to the receiving port queue, this task receives a message that notifies it that another message can be sent.  If the sender tries to send a second message with this option to the same port before the first notification arrives, the result is an error.  If both SEND_NOTIFY and SEND_TIMEOUT are specified, \b msg_send()\b0  will wait until the specified timeout has elapsed before invoking the SEND_NOTIFY option.\
  1538. \fs20 \
  1539. \fs28 SEND_INTERRUPT:  Specifies that \b msg_send()\b0  should return if a software interrupt occurs in this thread.\
  1540. \fs20 \
  1541. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Use MSG_OPTION_NONE to specify that none of the above options is wanted.\
  1542. \fs20 \
  1543. \fs28 \i timeout\i0 :  If the destination port is full and the SEND_TIMEOUT option has been specified, this value specifies the maximum wait time (in milliseconds).\
  1544. \fs20 \
  1545. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1546. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b msg_send()\b0  transmits a message from the current task to the port specified in the message header field.  The message consists of its header, followed by a variable number of data descriptors and data items.\
  1547. \fs20 \
  1548. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 If the \b msg_local_port\b0  field isn\'27t set to PORT_NULL, send rights to that port will be passed to the receiver of this message.  The receiver task can use that port to send a reply to this message.\
  1549. \fs20 \
  1550. \fs28 If the SEND_NOTIFY option is used and this call returns a SEND_WILL_NOTIFY code, you can expect to receive a notify message from the kernel.  This message will be either a NOTIFY_MSG_ACCEPTED or a NOTIFY_PORT_DELETED message, depending on what happened to the queued message.  The \b notify_port\b0  field\i  \i0 in these messages is the port to which the original message was sent.  The formats for these messages are defined in the header file \b sys/notify.h\b0 .\
  1551. \fs20 \
  1552. \fs28 See Chapter 2, \'aaUsing Mach Messages,\'ba for information on setting up messages and on writing Mach servers.\
  1553. \fs20 \
  1554. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  1555. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 /* From the handwritten part of a Mach server... */\
  1556. \fi0 while (TRUE)\
  1557. \fi0 \{        \
  1558. \fi0     /* Receive a request from a client. */\
  1559. \fi0     msg.head.msg_local_port = port;\
  1560. \fi0     msg.head.msg_size = sizeof(struct message);\
  1561. \fi0     ret = msg_receive(&msg.head, MSG_OPTION_NONE, 0);\
  1562. \fi0     if (ret != RCV_SUCCESS) /* ignore errors */; \
  1563. \fi0 \
  1564. \fi0     /* Feed the request into the server. */\
  1565. \fi0     (void)add_server(&msg, &reply);\
  1566. \fi0 \
  1567. \fi0     /* Send a reply to the client. */\
  1568. \fi0     reply.head.msg_local_port = port;\
  1569. \fi0     ret = msg_send(&reply.head, MSG_OPTION_NONE, 0);\
  1570. \fi0     if (ret != SEND_SUCCESS) /* ignore errors */; \
  1571. \fi0 \}\
  1572. \s25 \fi-2015 \f1 \fs28 \fs28 \
  1573. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 SEND_SUCCESS:  The message has been queued for the destination port.\
  1574. \fs20 \
  1575. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 SEND_INVALID_MEMORY:  The message header or body was not readable by the calling task, or the message body specified out-of-line data that was not readable.\
  1576. \fs20 \
  1577. \fs28 SEND_INVALID_PORT:  The message refers either to a port for which the current task does not have access, or to which access was explicitly removed from the current task (see \b port_deallocate()\b0 ) while waiting for the message to be posted, or a \b msg_type_name\b0  field in the message specifies rights that the name doesn\'27t denote in the task (for example, specifying MSG_TYPE_SEND and supplying a port set name).\
  1578. \fs20 \
  1579. \fs28 SEND_TIMED_OUT:  The message was not sent since the destination port was still full after \i timeout\i0  milliseconds.\
  1580. \fs20 \
  1581. \fs28 SEND_WILL_NOTIFY:  The destination port was full but the SEND_NOTIFY option was specified.  A notification message will be sent when the message can be posted.\
  1582. \fs20 \
  1583. \fs28 SEND_NOTIFY_IN_PROGRESS:  The SEND_NOTIFY option was specified but a notification request is already outstanding for this thread and given destination port.\
  1584. \fs20 \
  1585. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 \fs60 \
  1586. \fs28 port_allocate()\
  1587. \fs20 \
  1588. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  1589. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Create a port\
  1590. \fs28 \
  1591. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  1592. \fs10 \
  1593. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b port_allocate(\b0 task_t \i task\i0 , port_name_t *\i port_name\b \i0 )\
  1594. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  1595. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i task\i0 :  The task in which the new port is created (for example, use \b task_self()\b0  to specify the caller\'27s task).\
  1596. \fs20 \
  1597. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i port_name\i0 :  Returns the name used by \i task\i0  for the new port.\
  1598. \fs20 \
  1599. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1600. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b port_allocate()\b0  causes a port to be created for the specified task; the resulting port is returned in\i  port_name.  \i0 The target task initially has both send and receive rights to the port.  The new port isn\'27t a member of any port set.\
  1601. \fs20 \
  1602. \fs28 \s18 \f2 \fs24 \fs10 \
  1603. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 port_t         myport; \
  1604. \fi0 kern_return_t  error;\
  1605. \fi0 \
  1606. \fi0 if ((error=port_allocate(task_self(), &myport)) != KERN_SUCCESS) \{\
  1607. \fi0     mach_error("port_allocate failed", error); \
  1608. \fi0     exit(1);\
  1609. \fi0 \}\
  1610. \s25 \fi-2015 \f1 \fs28 \fs28 \
  1611. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  A port has been allocated.\
  1612. \fs20 \
  1613. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i task\i0  was invalid.\
  1614. \fs20 \
  1615. \fs28 KERN_RESOURCE_SHORTAGE:  No more port slots are available for this task.\
  1616. \fs20 \
  1617. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b \fs10 \
  1618. \fs28 \f0 \fs20     SEE ALSO    \fs28 \f1 port_deallocate()\
  1619. \fs20 \
  1620. \fs28 \s20 \fi0 \f0 \fs28 \fs60 \
  1621. \fs28 port_deallocate()\
  1622. \fs20 \
  1623. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  1624. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Deallocate a port\
  1625. \fs28 \
  1626. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  1627. \fs10 \
  1628. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b port_deallocate(\b0 task_t \i task\i0 , port_name_t \i port_name\b \i0 )\
  1629. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  1630. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i task\i0 :  The task that wants to relinquish rights to the port (for example, use \b task_self()\b0  to specify the caller\'27s task).\
  1631. \fs20 \
  1632. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i port_name\i0 : The name that \i task\i0  uses for the port to be deallocated.\
  1633. \fs20 \
  1634. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1635. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b port_deallocate()\b0  requests that the target task\'27s access to a port be relinquished.\
  1636. \fs20 \
  1637. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 If \i task\i0  has receive rights for the port and the port doesn\'27t have a backup port, these things happen:\
  1638. \fs20 \
  1639. \fs28 \s8 \li2494 \fi-378 \'b7    The port is destroyed.\
  1640. \'b7    All other tasks with send access to the port are notified of its destruction.\
  1641. \'b7    If the port is a member of a port set, it\'27s removed from the port set.\
  1642. \s4 \li2116 \fi0 \fs20 \
  1643. \fs28 If \i task\i0  has receive rights for the port and the port \i does\i0  have a backup port, then the following things happen:\
  1644. \fs20 \
  1645. \fs28 \s6 \li2494 \fi-378 \'b7    If the port is a member of a port set, it\'27s removed from the port set.\
  1646. \fs20 \
  1647. \fs28 \'b7    Send and receive rights for the port are sent to the backup port in a notification message (see \b port_set_backup()\b0 ).\
  1648. \fs20 \
  1649. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  1650. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 port_t         my_port; \
  1651. \fi0 kern_return_t  error;\
  1652. \fi0 \
  1653. \fi0 /* . . . */\
  1654. \fi0 \
  1655. \fi0 error=port_deallocate(task_self(), my_port);\
  1656. \fi0 if (error != KERN_SUCCESS) \{\
  1657. \fi0     mach_error("port_deallocate failed", error); \
  1658. \fi0     exit(1);\
  1659. \fi0 \}\
  1660. \s25 \fi-2015 \f1 \fs28 \fs28 \
  1661. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The port has been deallocated.\
  1662. \fs20 \
  1663. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i task\i0  was invalid or \i port_name\i0  doesn\'27t name a valid port.\
  1664. \fs20 \
  1665. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b \fs10 \
  1666. \fs28 \f0 \fs20     SEE ALSO    \fs28 \f1 port_allocate()\
  1667. \fs20 \
  1668. \fs28 \s20 \fi0 \f0 \fs28 \fs60 \
  1669. \fs28 port_extract_receive()\b0 , \b port_extract_send()\
  1670. \fs20 \
  1671. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  1672. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Remove access rights to a port and return them to the caller\
  1673. \fs28 \
  1674. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  1675. \fs10 \
  1676. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b port_extract_receive(\b0 task_t \i task\i0 , port_name_t \i its_name\i0 , port_t *\i its_port\b \i0 )\
  1677. \b0 kern_return_t \b port_extract_send(\b0 task_t \i task\i0 , port_name_t \i its_name\i0 , port_t *\i its_port\b \i0 )\
  1678. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  1679. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i task\i0 :  The task whose rights the caller takes.\
  1680. \fs20 \
  1681. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i its_name\i0 :  The name by which \i task\i0  knows the port.\
  1682. \fs20 \
  1683. \fs28 \i its_port\i0 :  Returns the receive or send rights.\
  1684. \fs20 \
  1685. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1686. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The functions \b port_extract_receive()\b0  and \b port_extract_send()\b0  remove the port access rights that \i task\i0  has for a port and return the rights to the caller.  This leaves \i task\i0  with no rights for the port.\
  1687. \fs20 \
  1688. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The \b port_extract_send()\b0  function extracts send rights; \i task\i0  can\'27t have receive rights for the named port.  The \b port_extract_receive()\b0 \i  \i0 function extracts receive rights.\
  1689. \fs20 \
  1690. \fs28 \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1691. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  1692. \fs20 \
  1693. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i task\i0  was invalid or \i its_name\i0  doesn\'27t name a port for which \i task\i0  has the required rights.\
  1694. \fs20 \
  1695. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1696. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b port_insert_send()\b0 , \b port_insert_receive()\
  1697. \fs20 \
  1698. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  1699. \fs28 port_insert_receive()\b0 , \b port_insert_send()\
  1700. \fs20 \
  1701. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  1702. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Give a task rights with a specific name\
  1703. \fs28 \
  1704. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  1705. \fs10 \
  1706. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b port_insert_receive(\b0 task_t \i task\i0 , port_t \i my_port\i0 , port_name_t \i its_name\b \i0 )\
  1707. \b0 kern_return_t \b port_insert_send(\b0 task_t \i task\i0 , port_t \i my_port\i0 , port_name_t \i its_name\b \i0 )\
  1708. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  1709. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i task\i0 :  The task getting the new rights.\
  1710. \fs20 \
  1711. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i my_port\i0 :  Rights supplied by the caller.\
  1712. \fs20 \
  1713. \fs28 \i its_name\i0 :  The name by which \i task\i0  will know the new rights.\
  1714. \fs20 \
  1715. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1716. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The functions \b port_insert_receive()\b0  and \b port_insert_send()\b0  give a task rights with a specific name.  If \i task\i0  already has rights named \i its_name\i0 , or has some other name for \i my_port\i0 , the operation will fail.  The \i its_name\i0  argument can\'27t be a predefined port, such as PORT_NULL.\
  1717. \fs20 \
  1718. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The \b port_insert_send()\b0  function inserts send rights, and \b port_insert_receive()\b0  inserts receive rights.\
  1719. \fs20 \
  1720. \fs28 \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1721. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  1722. \fs20 \
  1723. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_NAME_EXISTS:  \i task\i0  already has a right named \i its_name\i0 .\
  1724. \fs20 \
  1725. \fs28 KERN_FAILURE:  \i task\i0  already has rights to \i my_port\i0 .\
  1726. \fs20 \
  1727. \fs28 KERN_INVALID_ARGUMENT:  \i task\i0  was invalid or \i its_name\i0  was an invalid name.\
  1728. \fs20 \
  1729. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1730. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b port_extract_send()\b0 , \b port_extract_receive()\
  1731. \fs20 \
  1732. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  1733. \fs28 port_names()\
  1734. \fs20 \
  1735. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  1736. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get information about the port name space of a task \
  1737. \fs28 \
  1738. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  1739. \fs10 \
  1740. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b port_names(\b0 task_t \i task\i0 , port_name_array_t *\i port_names\i0 , unsigned int *\i port_names_count\i0 , port_type_array_t *\i port_types\i0 , unsigned int *\i port_types_count\b \i0 )\
  1741. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  1742. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i task\i0 :  The task whose port name space is queried.\
  1743. \fs20 \
  1744. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i port_names\i0 :  Returns the names of the ports and port sets in the port name space of \i task\i0 , in no particular order.  \
  1745. \fs20 \
  1746. \fs28 \i port_names_count\i0 :  Returns the number of names returned.\
  1747. \fs20 \
  1748. \fs28 \i port_types\i0 :  Returns the type of each corresponding name.  This indicates what kind of rights the task holds for the port, or whether the name refers to a port set.  The type is one of the following:  PORT_TYPE_SEND (send rights only), PORT_TYPE_RECEIVE_OWN (send and receive rights), PORT_TYPE_SET (the port is a port set).\
  1749. \fs20 \
  1750. \fs28 \i port_types_count\i0 :  Returns the same value as \i port_names_count\i0 .\
  1751. \fs20 \
  1752. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1753. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b port_names()\b0  returns information about the port name space of \i task\i0 .  It returns the port and port set names that are currently valid for \i task\i0 .  For each name, it also returns what type of rights \i task\i0  holds.\
  1754. \fs20 \
  1755. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The \i port_names\i0  and \i port_types\i0  arguments are arrays that are automatically allocated when the reply message is received.  You should use \b vm_deallocate()\b0  on them when the data is no longer needed.  \
  1756. \fs20 \
  1757. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  1758. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 kern_return_t      error;\
  1759. \fi0 port_name_array_t  names;\
  1760. \fi0 unsigned int       names_count, types_count;\
  1761. \fi0 port_type_array_t  types;\
  1762. \pard \s14 \li2116 \fi0 \ri503 \ql \
  1763. error=port_names(task_self(), &names, &names_count, &types,\
  1764. \fi0     &types_count);\
  1765. \fi0 if (error != KERN_SUCCESS) \{\
  1766. \fi0     mach_error("port_rename returned value of ", error);\
  1767. \fi0     exit(1);\
  1768. \fi0 \}\
  1769. \fi0 /* . . . */\
  1770. \fi0 error=vm_deallocate(task_self(), (vm_address_t)names, \
  1771. \fi0     sizeof(names)*names_count);\
  1772. \fi0 if (error != KERN_SUCCESS)\
  1773. \fi0     mach_error("Trouble freeing names", error);\
  1774. \fi0     \
  1775. \fi0 error=vm_deallocate(task_self(), (vm_address_t)types, \
  1776. \fi0     sizeof(names)*types_count);\
  1777. \fi0 if (error != KERN_SUCCESS)\
  1778. \fi0     mach_error("Trouble freeing types", error);\
  1779. \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  1780. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  1781. \fs20 \
  1782. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i task\i0  was invalid.\
  1783. \fs20 \
  1784. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1785. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b port_type()\b0 , \b port_status()\b0 , \b port_set_status()\
  1786. \fs20 \
  1787. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  1788. \fs28 port_rename()\
  1789. \fs20 \
  1790. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  1791. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Change the name by which a port or port set is known to a task\
  1792. \fs28 \
  1793. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  1794. \fs10 \
  1795. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b port_rename(\b0 task_t \i task\i0 , port_name_t \i old_name\i0 , port_name_t \i new_name\b \i0 )\
  1796. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  1797. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i task\i0 :  The task whose port name space is changed.\
  1798. \fs20 \
  1799. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i old_name\i0 :  The current name of the port or port set.\
  1800. \fs20 \
  1801. \fs28 \i new_name\i0 :  The new name for the port or port set.\
  1802. \fs20 \
  1803. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1804. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b port_rename()\b0  changes the name by which a port or port set is known to \i task.  \i0 The port name specified in \i new_name\i0  must not already be in use, and it can\'27t be a predefined port, such as PORT_NULL.  Currently, a name is a small integer.\
  1805. \fs20 \
  1806. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 One way to guarantee that a name isn\'27t already in use is to deallocate a port and then use its name as \i new_name\i0 .  Another way is to check all the existing names, using \b port_names()\b0 , before you call \b port_rename()\b0 .  If you choose another naming scheme, you should be prepared to try another name if \b port_rename()\b0  returns a KERN_NAME_EXISTS error.  \
  1807. \fs20 \
  1808. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  1809. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 #define MY_PORT  (port_name_t)99\
  1810. \fi0 \
  1811. \fi0 port_name_t       my_port; \
  1812. \fi0 kern_return_t     error;\
  1813. \pard \s14 \li2116 \fi0 \ri503 \ql \
  1814. error=port_allocate(task_self(),&my_port);\
  1815. \fi0 if (error != KERN_SUCCESS) \{\
  1816. \fi0     mach_error("port_allocate failed", error); \
  1817. \fi0     exit(1);\
  1818. \fi0 \}\
  1819. \fi0 \
  1820. error=port_rename(task_self(), my_port, MY_PORT);\
  1821. \fi0 if (error == KERN_NAME_EXISTS)\
  1822. \fi0     /* try again with a different name */;\
  1823. \fi0 else if (error != KERN_SUCCESS) \{\
  1824. \fi0         mach_error("port_rename failed", error);\
  1825. \fi0         exit(1);\
  1826. \fi0     \}\
  1827. \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  1828. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  1829. \fs20 \
  1830. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_NAME_EXISTS:  \i task\i0  already has a port or port set\i  \i0 named \i new_name.\
  1831. \fs20 \
  1832. \fs28 \i0 KERN_INVALID_ARGUMENT:  \i task\i0  was invalid, or \i task\i0  didn\'27t know any ports or port sets named \i old_name\i0 , or \i new_name\i0  was an invalid name.\
  1833. \fs20 \
  1834. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b \fs10 \
  1835. \fs28 \f0 \fs20     SEE ALSO    \fs28 \f1 port_names()\
  1836. \fs20 \
  1837. \fs28 \s20 \fi0 \f0 \fs28 \fs60 \
  1838. \fs28 port_set_add()\
  1839. \fs20 \
  1840. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  1841. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Move the named port into the named port set\
  1842. \fs28 \
  1843. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  1844. \fs10 \
  1845. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b port_set_add(\b0 task_t \i task\i0 , port_set_name_t \i set_name\i0 , port_name_t \i port_name\b \i0 )\
  1846. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  1847. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i task\i0 :  The task that has receive rights for the port set and port.\
  1848. \fs20 \
  1849. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i set_name\i0 :  \i task\i0 \'27s name for the port set.\
  1850. \fs20 \
  1851. \fs28 \i port_name\i0 :  \i task\i0 \'27s name for the port.\
  1852. \fs20 \
  1853. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1854. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b port_set_add()\b0  moves the named port into the named port set.  The \i task\i0  must have receive rights for the port.  If the port is already a member of another port set, it\'27s removed from that set first.\
  1855. \fs20 \
  1856. \fs28 \s18 \f2 \fs24 \fs10 \
  1857. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 kern_return_t    error;\
  1858. \fi0 port_set_name_t  set_name;\
  1859. \fi0 port_t           my_port;\
  1860. \pard \s14 \li2116 \fi0 \ri503 \ql \
  1861. error=port_set_allocate(task_self(),&set_name);\
  1862. \fi0 if (error != KERN_SUCCESS) \{\
  1863. \fi0     mach_error("port_set_allocate failed", error); \
  1864. \fi0     exit(1);\
  1865. \fi0 \}\
  1866. \fi0 \
  1867. error=port_allocate(task_self(),&my_port);\
  1868. \fi0 if (error != KERN_SUCCESS) \{\
  1869. \fi0     mach_error("port_allocate failed", error); \
  1870. \fi0     exit(1);\
  1871. \fi0 \}\
  1872. \fi0 \
  1873. error=port_set_add(task_self(), set_name, my_port);\
  1874. \fi0 if (error != KERN_SUCCESS) \{\
  1875. \fi0     mach_error("port_allocate failed", error); \
  1876. \fi0     exit(1);\
  1877. \fi0 \}\
  1878. \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  1879. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  1880. \fs20 \
  1881. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_NOT_RECEIVER:  \i task \i0 doesn\'27t have receive rights for the port\i .\
  1882. \fs20 \
  1883. \fs28 \i0 KERN_INVALID_ARGUMENT:  \i task\i0  was invalid, or \i set_name\i0  doesn\'27t name a valid port set, or \i port_name\i0  doesn\'27t name a valid port.\
  1884. \fs20 \
  1885. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b \fs10 \
  1886. \fs28 \f0 \fs20     SEE ALSO    \fs28 \f1 port_set_remove()\
  1887. \fs20 \
  1888. \fs28 \s20 \fi0 \f0 \fs28 \fs60 \
  1889. \fs28 port_set_allocate()\
  1890. \fs20 \
  1891. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  1892. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Create a port set\
  1893. \fs28 \
  1894. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  1895. \fs10 \
  1896. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b port_set_allocate(\b0 task_t \i task\i0 , port_set_name_t *\i set_name\b \i0 )\
  1897. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  1898. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i task\i0 :  The task in which the new port set is created.\
  1899. \fs20 \
  1900. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i set_name\i0 :  Returns \i task\i0 \'27s name for the new port set.\
  1901. \fs20 \
  1902. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1903. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b port_set_allocate()\b0  causes a port set to be created for the specified task; the resulting set\'27s name is returned in \i set_name.  \i0 The new port set is empty.\
  1904. \fs20 \
  1905. \fs28 \s18 \f2 \fs24 \fs10 \
  1906. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 kern_return_t    error;\
  1907. \fi0 port_set_name_t  set_name;\
  1908. \fi0 \
  1909. \fi0 error=port_set_allocate(task_self(),&set_name);\
  1910. \fi0 if (error != KERN_SUCCESS) \{\
  1911. \fi0     mach_error("port_set_allocate failed", error); \
  1912. \fi0     exit(1);\
  1913. \fi0 \}\
  1914. \s25 \fi-2015 \f1 \fs28 \fs28 \
  1915. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  1916. \fs20 \
  1917. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i task\i0  was invalid.\
  1918. \fs20 \
  1919. \fs28 KERN_RESOURCE_SHORTAGE:  The kernel ran out of memory.\
  1920. \fs20 \
  1921. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1922. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b port_set_deallocate()\b0 , \b port_set_add()\
  1923. \fs20 \
  1924. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  1925. \fs28 port_set_backlog()\
  1926. \fs20 \
  1927. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  1928. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Set the size of the port queue\
  1929. \fs28 \
  1930. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  1931. \fs10 \
  1932. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b port_set_backlog(\b0 task_t \i task\i0 , port_name_t \i port_name\i0 , int \i backlog\b \i0 )\
  1933. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  1934. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i task\i0 :  The task that has receive rights for the named port (for example, use \b task_self()\b0  to specify the caller\'27s task).\
  1935. \fs20 \
  1936. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i port_name\i0 :  \i task\i0 \'27s name for the port.\
  1937. \fs20 \
  1938. \fs28 \i backlog\i0 :  The new backlog to be set.\
  1939. \fs20 \
  1940. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1941. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b port_set_backlog()\b0  changes the backlog value on the specified port (the port\'27s backlog value is the number of unreceived messages that are allowed in its message queue before the kernel will refuse to accept any more sends to that port).  \
  1942. \fs20 \
  1943. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The task specified by \i task\i0  must have receive rights for the named port.\
  1944. \fs20 \
  1945. \fs28 The maximum backlog value is the constant PORT_BACKLOG_MAX.  You can get a port\'27s current backlog value by calling \b port_status()\b0 .  \
  1946. \fs20 \
  1947. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  1948. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 #define MY_BACKLOG  10\
  1949. \fi0 \
  1950. \fi0 kern_return_t   error;\
  1951. \fi0 port_t          my_port;\
  1952. \fi0 \
  1953. \fi0 error=port_allocate(task_self(),&my_port);\
  1954. \fi0 if (error != KERN_SUCCESS) \{\
  1955. \fi0     mach_error("port_allocate failed", error); \
  1956. \fi0     exit(1);\
  1957. \fi0 \}\
  1958. \fi0 \
  1959. \fi0 error=port_set_backlog(task_self(), my_port, MY_BACKLOG);\
  1960. \fi0 if (error!=KERN_SUCCESS)\
  1961. \fi0     mach_error("Call to port_set_backlog failed", error);\
  1962. \s25 \fi-2015 \f1 \fs28 \fs28 \
  1963. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The backlog value has been changed.\
  1964. \fs20 \
  1965. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_NOT_RECEIVER:  \i task \i0 doesn\'27t have receive rights for the port.\
  1966. \fs20 \
  1967. \fs28 KERN_INVALID_ARGUMENT:  \i task\i0  was invalid, or \i port_name\i0  doesn\'27t name a valid port, or the desired backlog wasn\'27t greater than 0, or the desired backlog was greater than PORT_BACKLOG_MAX.\
  1968. \fs20 \
  1969. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1970. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b msg_send()\b0 , \b port_status()\
  1971. \fs20 \
  1972. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  1973. \fs28 port_set_backup()\
  1974. \fs20 \
  1975. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  1976. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Set the backup port for a port\
  1977. \fs28 \
  1978. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  1979. \fs10 \
  1980. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b port_set_backup(\b0 task_t \i task\i0 , port_name_t \i port_name\i0 , port_t \i backup\i0 , port_t *\i previous\b \i0 )\
  1981. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  1982. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i task\i0 :  The task that has receive rights for the named port (for example, use \b task_self()\b0  to specify the caller\'27s task).\
  1983. \fs20 \
  1984. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i port_name\i0 :  \i task\i0 \'27s name for the port right.\
  1985. \fs20 \
  1986. \fs28 \i backup\i0 :  The new backup port.  If you want to disable the current backup port without setting a new one, set this to PORT_NULL.\
  1987. \fs20 \
  1988. \fs28 \i previous\i0 :  Returns the previous backup port.\
  1989. \fs20 \
  1990. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  1991. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 Use this function to keep a port alive despite its being deallocated by its receiver.  If the call to \b port_set_backup()\b0  is successful, then whenever \i port_name\i0  is deallocated by its receiver, \i backup\i0  will receive a notification message with receive and send rights for\i  port_name\i0 .  As far as \i task\i0  is concerned, the port will be deleted; however, as far as senders to the port are concerned, the port will continue to exist.\
  1992. \fs20 \
  1993. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 To let a port die naturally after its backup port has been set, call \b port_set_backup()\b0  on it with \i backup\i0  set to PORT_NULL.  \
  1994. \fs20 \
  1995. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  1996. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 kern_return_t    error;\
  1997. \fi0 port_t           my_port, backup_port, previous_port;\
  1998. \fi0     \
  1999. \fi0 error=port_allocate(task_self(),&my_port);\
  2000. \fi0 if (error != KERN_SUCCESS) \{\
  2001. \fi0     mach_error("port_allocate failed", error); \
  2002. \fi0     exit(1);\
  2003. \fi0 \}\
  2004. \pard \s14 \li2116 \fi0 \ri503 \ql \
  2005. error=port_allocate(task_self(),&backup_port);\
  2006. \fi0 if (error != KERN_SUCCESS) \{\
  2007. \fi0     mach_error("port_allocate failed", error); \
  2008. \fi0     exit(1);\
  2009. \fi0 \}\
  2010. \fi0 \
  2011. error=port_set_backup(task_self(), my_port, backup_port,\
  2012. \fi0     &previous_port);\
  2013. \fi0 if (error!=KERN_SUCCESS)\
  2014. \fi0     mach_error("Call to port_set_backlog failed", error);\
  2015. \fi0 \
  2016. \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  2017. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  2018. \fs20 \
  2019. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i task\i0  was invalid, or \i port_name\i0  doesn\'27t name a valid port.\
  2020. \fs20 \
  2021. \fs28 KERN_NOT_RECEIVER:  \i task\i0  doesn\'27t have receive rights for \i port_name\i0 .\
  2022. \fs20 \
  2023. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 \fs60 \
  2024. \fs28 port_set_deallocate()\
  2025. \fs20 \
  2026. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  2027. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Destroy a port set\
  2028. \fs28 \
  2029. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  2030. \fs10 \
  2031. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b port_set_deallocate(\b0 task_t \i task\i0 , port_set_name_t \i set_name\b \i0 )\
  2032. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  2033. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i task\i0 :  The task that has receive rights for the port set to be destroyed.\
  2034. \fs20 \
  2035. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i set_name\i0 :  \i task\i0 \'27s name for the doomed port set.\
  2036. \fs20 \
  2037. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2038. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b port_set_deallocate()\b0  requests that the port set of \i task \i0 be destroyed.  If the port set isn\'27t empty, any members are first removed.\
  2039. \fs20 \
  2040. \fs28 \s18 \f2 \fs24 \fs10 \
  2041. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 kern_return_t   error;\
  2042. \fi0 port_set_name_t set_name;\
  2043. \fi0 \
  2044. \fi0 error=port_set_deallocate(task_self(),set_name);\
  2045. \fi0 if (error != KERN_SUCCESS) \{\
  2046. \fi0     mach_error("port_set_deallocate failed", error); \
  2047. \fi0     exit(1);\
  2048. \fi0 \}\
  2049. \s25 \fi-2015 \f1 \fs28 \fs28 \
  2050. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  2051. \fs20 \
  2052. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i task\i0  was invalid or \i set_name\i0  doesn\'27t name a valid port set.\
  2053. \fs20 \
  2054. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b \fs10 \
  2055. \fs28 \f0 \fs20     SEE ALSO    \fs28 \f1 port_set_allocate()\
  2056. \fs20 \
  2057. \fs28 \s20 \fi0 \f0 \fs28 \fs60 \
  2058. \fs28 port_set_remove()\
  2059. \fs20 \
  2060. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  2061. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Remove the named port from a port set\
  2062. \fs28 \
  2063. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  2064. \fs10 \
  2065. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b port_set_remove(\b0 task_t \i task\i0 , port_name_t \i port_name\b \i0 )\
  2066. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  2067. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i task\i0 :  The task that has receive rights for the port and port set.\
  2068. \fs20 \
  2069. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i port_name\i0 :  \i task\i0 \'27s name for the receive rights to be removed.\
  2070. \fs20 \
  2071. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2072. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b port_set_remove()\b0  removes the named port from a port set.  The \i task\i0  must have receive rights for the port, and the port must be a member of a port set.\
  2073. \fs20 \
  2074. \fs28 \s18 \f2 \fs24 \fs10 \
  2075. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 error=port_set_remove(task_self(), my_port);\
  2076. \fi0 if (error != KERN_SUCCESS) \{\
  2077. \fi0     mach_error("port_set_remove failed", error); \
  2078. \fi0     exit(1);\
  2079. \fi0 \}\
  2080. \s25 \fi-2015 \f1 \fs28 \fs28 \
  2081. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  2082. \fs20 \
  2083. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_NOT_RECEIVER:  \i task\i0  doesn\'27t have receive rights for the port.\
  2084. \fs20 \
  2085. \fs28 KERN_NOT_IN_SET:  The port isn\'27t a member of a set.\
  2086. \fs20 \
  2087. \fs28 KERN_INVALID_ARGUMENT:  \i task\i0  was invalid or \i port_name\i0  doesn\'27t name a valid port.\
  2088. \fs20 \
  2089. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b \fs10 \
  2090. \fs28 \f0 \fs20     SEE ALSO    \fs28 \f1 port_set_add()\
  2091. \fs20 \
  2092. \fs28 \s20 \fi0 \f0 \fs28 \fs60 \
  2093. \fs28 port_set_status()\
  2094. \fs20 \
  2095. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  2096. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get the members of a port set\
  2097. \fs28 \
  2098. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  2099. \fs10 \
  2100. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b port_set_status(\b0 task_t \i task\i0 , port_set_name_t \i set_name\i0 , port_name_array_t *\i members\i0 , unsigned int *\i members_count\b \i0 )\
  2101. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  2102. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i task\i0 :  The task whose port set is queried.\
  2103. \fs20 \
  2104. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i set_name\i0 :  \i task\'27s\i0  name for the port set.\
  2105. \fs20 \
  2106. \fs28 \i members\i0 :  Returns \i task\i0 \'27s names for the members of its port set.\
  2107. \fs20 \
  2108. \fs28 \i members_count\i0 :  Returns the number of port names in \i members\i0 .\
  2109. \fs20 \
  2110. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2111. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b port_set_status()\b0  returns a list of the ports in a port set.  The \i members\i0  argument is an array that\'27s automatically allocated when the reply message is received.  You should use \b vm_deallocate()\b0  on it when the data is no longer needed.\
  2112. \fs20 \
  2113. \fs28 \s18 \f2 \fs24 \fs10 \
  2114. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 error=port_set_status(task_self(), set_name, &members, \
  2115. \fi0    &members_count);\
  2116. \fi0 if (error != KERN_SUCCESS) \{\
  2117. \fi0     mach_error("port_set_status failed", error); \
  2118. \fi0     exit(1);\
  2119. \fi0 \}\
  2120. \pard \s14 \li2116 \fi0 \ri503 \ql \
  2121. /* . . . */\
  2122. \fi0 error=vm_deallocate(task_self(), (vm_address_t)members, \
  2123. \fi0     sizeof(members)*members_count);\
  2124. \fi0 if (error != KERN_SUCCESS)\
  2125. \fi0     mach_error("Trouble freeing members", error);\
  2126. \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  2127. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  2128. \fs20 \
  2129. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i task\i0  was invalid or \i set_name\i0  doesn\'27t name a valid port set.\
  2130. \fs20 \
  2131. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b \fs10 \
  2132. \fs28 \f0 \fs20     SEE ALSO    \fs28 \f1 port_status()\
  2133. \fs20 \
  2134. \fs28 \s20 \fi0 \f0 \fs28 \fs60 \
  2135. \fs28 port_status()\
  2136. \fs20 \
  2137. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  2138. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Examine a port\'27s current status\
  2139. \fs28 \
  2140. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  2141. \fs10 \
  2142. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b port_status(\b0 task_t \i task\i0 , port_name_t \i port_name\i0 , port_set_name_t *\i port_set_name\i0 , int *\i num_msgs\i0 , int *\i backlog\i0 , boolean_t *\i owner\i0 , boolean_t *\i receiver\b \i0 )\
  2143. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  2144. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i task\i0 :  The task that has receive rights for the port in question (for example, use \b task_self()\b0  to specify the caller\'27s task).\
  2145. \fs20 \
  2146. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i port_name\i0 :  \i task\i0 \'27s name for the port right.\
  2147. \fs20 \
  2148. \fs28 \i port_set_name\i0 :  Returns \i task\i0 \'27s name for the port set that the named port belongs to, or PORT_NULL if it isn\'27t in a set.  \
  2149. \fs20 \
  2150. \fs28 \i num_msgs\i0 :  Returns the number of messages queued on this port.  If \i task\i0  isn\'27t the port\'27s receiver, the number of messages will be returned as negative.\
  2151. \fs20 \
  2152. \fs28 \i backlog\i0 :  Returns the number of messages that can be queued to this port without causing the sender to block.\
  2153. \fs20 \
  2154. \fs28 \i owner\i0 :  Returns the same value as \i receiver\i0 , since ownership rights and receive rights aren\'27t separable.\
  2155. \fs20 \
  2156. \fs28 \i receiver\i0 :  Returns true if \i task\i0  has receive rights to \i port_name\i0 ; otherwise, returns false.\
  2157. \fs20 \
  2158. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2159. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b port_status()\b0  returns the current port status associated with \i port_name\i0 .\
  2160. \fs20 \
  2161. \fs28 \s18 \f2 \fs24 \fs10 \
  2162. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 error=port_status(task_self(), my_port, &port_set_name, &num_msgs, \
  2163. \fi0     &backlog, &owner, &receiver);\
  2164. \fi0 if (error!=KERN_SUCCESS)\
  2165. \fi0     mach_error("Call to port_status failed", error);\
  2166. \s25 \fi-2015 \f1 \fs28 \fs28 \
  2167. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The data has been retrieved.\
  2168. \fs20 \
  2169. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i task\i0  was invalid or \i port_name\i0  doesn\'27t name a valid port.\
  2170. \fs20 \
  2171. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2172. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b port_set_backlog()\b0 , \b port_set_status()\
  2173. \fs20 \
  2174. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  2175. \fs28 port_type()\
  2176. \fs20 \
  2177. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  2178. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Determine the access rights of a task for a specific port name\
  2179. \fs28 \
  2180. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  2181. \fs10 \
  2182. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b port_type(\b0 task_t \i task\i0 , port_name_t \i port_name\i0 , port_type_t *\i port_type\b \i0 )\
  2183. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  2184. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i task\i0 :  The task whose port name space is queried.\
  2185. \fs20 \
  2186. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i port_name\i0 :  The name being queried.  \
  2187. \fs20 \
  2188. \fs28 \i port_type\i0 :  Returns a value that indicates what kind of rights the task holds for the port, or whether the name refers to a port set.  This value is one of the following:  PORT_TYPE_SEND (send rights only), PORT_TYPE_RECEIVE_OWN (send and receive rights), PORT_TYPE_SET (the port is a port set).\
  2189. \fs20 \
  2190. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2191. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b port_type()\b0  returns information about \i task\'27\i0 s rights for a specific name in its port name space.\
  2192. \fs20 \
  2193. \fs28 \s18 \f2 \fs24 \fs10 \
  2194. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 error=port_type(task_self(), port, &type);\
  2195. \fi0 if (error != KERN_SUCCESS)\
  2196. \fi0     mach_error("Couldn\'27t get type of port", error); \
  2197. \s25 \fi-2015 \f1 \fs28 \fs28 \
  2198. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  2199. \fs20 \
  2200. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i task\i0  was invalid or \i task\i0  didn\'27t have any rights named \i port_name\i0 .\
  2201. \fs20 \
  2202. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2203. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b port_names()\b0 , \b port_status()\b0 , \b port_set_status()\
  2204. \fs20 \
  2205. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  2206. \fs28 processor_assign(), processor_control(), processor_exit(), processor_get_assignment(), processor_start()\
  2207. \fs20 \
  2208. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  2209. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Control a processor\
  2210. \fs28 \
  2211. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  2212. \fs10 \
  2213. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b processor_assign(\b0 processor_t \i processor\i0 , processor_set_t \i new_processor_set\i0 , boolean_t \i wait\b \i0 )\
  2214. \b0 kern_return_t \b processor_control(\b0 processor_t \i processor\i0 , processor_info_t \i info\i0 , long *\i count\b \i0 )\
  2215. \b0 kern_return_t \b processor_exit(\b0 processor_t \i processor\b \i0 )\
  2216. \b0 kern_return_t \b processor_get_assignment(\b0 processor_t \i processor\i0 , processor_set_t *\i processor_set\b \i0 )\
  2217. \b0 kern_return_t \b processor_start(\b0 processor_t \i processor\b \i0 )\
  2218. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  2219. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 \b processor_assign()\b0  changes the processor set to which \i processor\i0  is assigned.  \b processor_control()\b0  returns information about \i processor\i0 .  \b processor_exit()\b0  shuts down \i processor\i0 .  \b processor_get_assignment()\b0  returns the processor set to which \i processor\i0  is assigned.  \b processor_start()\b0  starts up \i processor\i0 .\
  2220. \fs20 \
  2221. \fs28 \pard \s37 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Note:  \b0 \fs28 \f1 These functions are useful only on multiprocessor systems.  \
  2222. \fs20 \
  2223. \fs28 \s20 \f0 \b \fs28 \fs60 \
  2224. \fs28 processor_info() \
  2225. \fs20 \
  2226. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  2227. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get information about a processor\
  2228. \fs28 \
  2229. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  2230. \fs10 \
  2231. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b processor_info(\b0 processor_t \i processor\i0 , int \i flavor\i0 , host_t *\i host\i0 , processor_info_t \i processor_info\i0 , unsigned int *\i processor_info_count\b \i0 )\
  2232. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  2233. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i processor\i0 :  The processor for which information is to be obtained.\
  2234. \fs20 \
  2235. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i flavor\i0 :  The type of information that is wanted.  Currently only PROCESSOR_BASIC_INFO is implemented.\
  2236. \fs20 \
  2237. \fs28 \i host\i0 :  Returns the non-privileged host port for the host on which the processor resides.\
  2238. \fs20 \
  2239. \fs28 \i processor_info\i0 :  Returns information about the processor specified by \i processor\i0 .\
  2240. \fs20 \
  2241. \fs28 \i processor_info_count\i0 :  Size of the info structure.  Should be PROCESSOR_BASIC_INFO_COUNT when \i flavor\i0  is PROCESSOR_BASIC_INFO.\
  2242. \fs20 \
  2243. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2244. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 Returns the selected information array for a processor, as specified by \i flavor\i0 .  The \i processor_info\i0  argument is an array of integers that is supplied by the caller and filled with specified information.  The \i processor_info_count\i0  argument is supplied as the maximum number of integers in \i processor_info\i0 .  On return, it contains the actual number of integers in \i processor_info\i0 .\
  2245. \fs20 \
  2246. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Basic information is defined by PROCESSOR_BASIC_INFO.  The size of this information is defined by PROCESSOR_BASIC_INFO_COUNT.  The data structures used by PROCESSOR_BASIC_INFO are defined in the header file \b mach/processor_info.h\b0 .  Possible values of the \b cpu_type\b0  and \b cpu_subtype\b0  fields are defined in the header file \b mach/machine.h\b0 .\
  2247. \fs20 \
  2248. \fs28 \pard \s12 \li2494 \fi0 \ri1007 \ql \f2 \fs24 typedef int *processor_info_t;  /* variable length array of int */\
  2249. \fi0 \
  2250. \fi0 /* one interpretation of info is */\
  2251. \fi0 struct processor_basic_info \{\
  2252. \fi0     cpu_type_t     cpu_type;    /* cpu type */\
  2253. \fi0     cpu_subtype_t  cpu_subtype; /* cpu subtype */\
  2254. \fi0     boolean_t      running;     /* is processor running? */\
  2255. \fi0     int            slot_num;    /* slot number */\
  2256. \fi0     boolean_t      is_master;   /* is this the master processor */\
  2257. \fi0 \};\
  2258. \fi0 \
  2259. \fi0 typedef struct processor_basic_info *processor_basic_info_t;\
  2260. \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs28 \
  2261. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 kern_return_t                  error;\
  2262. \fi0 host_t                         host;\
  2263. \fi0 unsigned int                   list_size, info_count;\
  2264. \fi0 struct processor_basic_info    info;\
  2265. \fi0 processor_array_t              list;\
  2266. \pard \s14 \li2116 \fi0 \ri503 \ql \
  2267. /* Get the processor port. */\
  2268. \fi0 error=host_processors(host_priv_self(), &list, &list_size);\
  2269. \fi0 if ((error!=KERN_SUCCESS) || (list_size < 1))\{\
  2270. \fi0     mach_error("Error calling host_processors (are you root?)",\
  2271. \fi0         error);\
  2272. \fi0     exit(1);\
  2273. \fi0 \}\
  2274. \fi0 \
  2275. /* Get information about the processor. */\
  2276. \fi0 info_count=PROCESSOR_BASIC_INFO_COUNT;\
  2277. \fi0 error=processor_info(list[0], PROCESSOR_BASIC_INFO, &host,\
  2278. \fi0     (processor_info_t)&info, &info_count);\
  2279. \fi0 if (error != KERN_SUCCESS)\
  2280. \fi0     mach_error("Error calling processor_info", error);\
  2281. \fi0 \
  2282. /* Now that we\'27re done with the processor port, free it. */\
  2283. \fi0 vm_deallocate(task_self(), (vm_address_t)list, \
  2284. \fi0     sizeof(list)*list_size);\
  2285. \fi0 if (error!=KERN_SUCCESS)\
  2286. \fi0     mach_error("Trouble freeing list", error);\
  2287. \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  2288. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  2289. \fs20 \
  2290. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i processor\i0  isn\'27t a known processor.  \
  2291. \fs20 \
  2292. \fs28 MIG_ARRAY_TOO_LARGE:  Returned info array is too large for \i processor_info\i0 .  The \i processor_info\i0  argument is filled as much as possible, and \i processor_info_count\i0  is set to the number of elements that would be returned if there were enough room.  \
  2293. \fs20 \
  2294. \fs28 KERN_FAILURE:  \i flavor\i0  isn\'27t recognized or \i processor_info_count\i0  is too small.\
  2295. \fs20 \
  2296. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2297. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b processor_start()\b0 , \b processor_exit()\b0 , \b processor_control()\b0 , \b host_processors()\
  2298. \fs20 \
  2299. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  2300. \fs28 processor_set_create()\
  2301. \fs20 \
  2302. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  2303. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Create a new processor set\
  2304. \fs28 \
  2305. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  2306. \fs10 \
  2307. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t\b  processor_set_create(\b0 host_t \i host\i0 , port_t *\i new_set\i0 , port_t *\i new_name\b \i0 )\
  2308. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  2309. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 This function creates a new processor set on \i host\i0 .\
  2310. \fs20 \
  2311. \fs28 \pard \s37 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Note:  \b0 \fs28 \f1 This function is useful only on multiprocessor systems.  \
  2312. \fs20 \
  2313. \fs28 \s20 \f0 \b \fs28 \fs60 \
  2314. \fs28 processor_set_default() \
  2315. \fs20 \
  2316. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  2317. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get the port of the default processor set\
  2318. \fs28 \
  2319. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  2320. \fs10 \
  2321. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b processor_set_default(\b0 host_t \i host\i0 , processor_set_t *\i default_set\b \i0 )\
  2322. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  2323. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i host\i0 :  The host whose default processor set is requested.\
  2324. \fs20 \
  2325. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i default_set\i0 :  Returns the name (nonprivileged) port for the default processor set.\
  2326. \fs20 \
  2327. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2328. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The default processor set is used by all threads, tasks, and processors that aren\'27t explicitly assigned to other sets.  This function returns a port that can be used to obtain information about this set (for example, how many threads are assigned to it).  This port isn\'27t privileged and thus can\'27t be used to perform operations on that set; call \b host_processor_set_priv()\b0  after \b processor_set_default()\b0  to get the privileged port.\
  2329. \fs20 \
  2330. \fs28 \s18 \f2 \fs24 \fs10 \
  2331. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 error=processor_set_default(host_self(), &default_set);\
  2332. \fi0 if (error!=KERN_SUCCESS)\{\
  2333. \fi0     mach_error("Error calling processor_set_default", error);\
  2334. \fi0     exit(1);\
  2335. \fi0 \}\
  2336. \s25 \fi-2015 \f1 \fs28 \fs28 \
  2337. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  2338. \fs20 \
  2339. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i host\i0  is not a host.\
  2340. \fs20 \
  2341. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2342. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b processor_set_info()\b0 , \b task_assign()\b0 , \b thread_assign()\
  2343. \fs20 \
  2344. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  2345. \fs28 processor_set_destroy()\
  2346. \fs20 \
  2347. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  2348. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Delete a processor set\
  2349. \fs28 \
  2350. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  2351. \fs10 \
  2352. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b processor_set_destroy(\b0 processor_set_t\i  processor_set\b \i0 )\
  2353. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  2354. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 This function destroys \i processor_set\i0 , reassigning all of its tasks, threads, and processors to the default processor set.\
  2355. \fs20 \
  2356. \fs28 \pard \s37 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Note:  \b0 \fs28 \f1 This function is useful only on multiprocessor systems.  \
  2357. \fs20 \
  2358. \fs28 \s20 \f0 \b \fs28 \fs60 \
  2359. \fs28 processor_set_info()\
  2360. \fs20 \
  2361. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  2362. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get information about a processor set\
  2363. \fs28 \
  2364. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  2365. \fs10 \
  2366. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b processor_set_info(\b0 processor_set_t \i processor_set\i0 , int \i flavor\i0 , host_t *\i host\i0 , processor_set_info_t \i processor_set_info\i0 , unsigned int *\i processor_set_info_count\i0 )\
  2367. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs28 \
  2368. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i processor_set\i0 :  The processor set for which information is to be obtained.\
  2369. \fs20 \
  2370. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i flavor\i0 :  The type of information that is wanted.  Should be PROCESSOR_SET_BASIC_INFO or PROCESSOR_SET_SCHED_INFO.\
  2371. \fs20 \
  2372. \fs28 \i host\i0 :  Returns the nonprivileged host port for the host on which the processor set resides.\
  2373. \fs20 \
  2374. \fs28 \i processor_set_info\i0 :  Returns information about the processor set specified by \i processor_set\i0 .  \
  2375. \fs20 \
  2376. \fs28 \i processor_set_info_count\i0 :  Size of the info structure.  Should be PROCESSOR_SET_BASIC_INFO_COUNT when \i flavor\i0  is PROCESSOR_SET_BASIC_INFO, and PROCESSOR_SET_SCHED_INFO_COUNT when \i flavor\i0  is PROCESSOR_SET_SCHED_INFO.\
  2377. \fs20 \
  2378. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2379. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 Returns the selected information array for a processor set, as specified by \i flavor\i0 .  The \i processor_set_info\i0  argument is an array of integers that is supplied by the caller, and filled with specified information.  The \i processor_set_info_count\i0  argument is supplied as the maximum number of integers in \i processor_set_info\i0 .  On return, it contains the actual number of integers in \i processor_set_info\i0 .\
  2380. \fs20 \
  2381. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Basic information is defined by PROCESSOR_SET_BASIC_INFO.  The size of this information is defined by PROCESSOR_SET_BASIC_INFO_COUNT.  The \b load_average\b0  and \b mach_factor\b0  fields are scaled by the constant LOAD_SCALE (that is, the integer value returned is the load average or Mach factor multiplied by LOAD_SCALE).  \
  2382. \fs20 \
  2383. \fs28 The \i Mach factor\i0 , like the UNIX load average, is a measurement of how busy the system is.  Unlike the load average, higher Mach factors mean that the system is less busy.  The Mach factor tells you how much of a CPU you have available for running an application.  For example, on a single-processor system with one job running, the Mach factor is 0.5; this means if another job starts running it will get half of the CPU.  (Two jobs will be running, each getting half the CPU.)  On a single-processor system, the Mach factor is between zero and one.  On a multiprocessor system, the Mach factor can go over one.  For example, a three-processor system with one job running has a Mach factor of 2.0, since two processors are available to new jobs.\
  2384. \fs20 \
  2385. \fs28 \pard \s12 \li2494 \fi0 \ri1007 \ql \f2 \fs24 struct processor_set_basic_info \{\
  2386. \fi0     int  processor_count;   /* number of processors */\
  2387. \fi0     int  task_count;        /* number of tasks */\
  2388. \fi0     int  thread_count;      /* number of threads */\
  2389. \fi0     int  load_average;      /* scaled load average */\
  2390. \fi0     int  mach_factor;       /* scaled mach factor */\
  2391. \fi0 \};\
  2392. \fi0 typedef struct processor_set_basic_info *processor_set_basic_info_t;\
  2393. \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \f1 \fs28 \fs20 \
  2394. \fs28 Scheduling information is defined by PROCESSOR_SET_SCHED_INFO.  The size of this information is given by PROCESSOR_SET_SCHED_INFO_COUNT.\
  2395. \fs20 \
  2396. \fs28 \pard \s12 \li2494 \fi0 \ri1007 \ql \f2 \fs24 struct processor_set_sched_info \{\
  2397. \fi0     int  policies;          /* allowed policies */\
  2398. \fi0     int  max_priority;      /* max priority for new threads */\
  2399. \fi0 \};\
  2400. \fi0 typedef struct processor_set_sched_info *processor_set_sched_info_t;\
  2401. \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs28 \
  2402. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 kern_return_t                    error;\
  2403. \fi0 host_t                           host;\
  2404. \fi0 unsigned int                     info_count;\
  2405. \fi0 struct processor_set_basic_info  info;\
  2406. \fi0 processor_set_t                  default_set;\
  2407. \pard \s14 \li2116 \fi0 \ri503 \ql \
  2408. error=processor_set_default(host_self(), &default_set);\
  2409. \fi0 if (error!=KERN_SUCCESS)\{\
  2410. \fi0     mach_error("Error calling processor_set_default", error);\
  2411. \fi0     exit(1);\
  2412. \fi0 \}\
  2413. \fi0 \
  2414. info_count=PROCESSOR_SET_BASIC_INFO_COUNT;\
  2415. \fi0 error=processor_set_info(default_set, PROCESSOR_SET_BASIC_INFO,\
  2416. \fi0    &host, (processor_set_info_t)&info, &info_count);\
  2417. \fi0 if (error != KERN_SUCCESS)\
  2418. \fi0     mach_error("Error calling processor_set_info", error);\
  2419. \fi0 \
  2420. printf("The UNIX load average is %f\\n", \
  2421. \fi0     (float)info.load_average/LOAD_SCALE);\
  2422. \fi0 printf("The Mach factor is %f\\n", (float)info.mach_factor/LOAD_SCALE);\
  2423. \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  2424. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  2425. \fs20 \
  2426. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i processor_set\i0  is not a processor set, or \i flavor\i0  is not recognized.\
  2427. \fs20 \
  2428. \fs28 KERN_FAILURE:  \i processor_set_info_count\i0  is less than what it should be.\
  2429. \fs20 \
  2430. \fs28 MIG_ARRAY_TOO_LARGE:  Returned info array is too large for \i processor_set_info\i0 .\
  2431. \fs20 \
  2432. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2433. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b processor_set_create()\b0 , \b processor_set_default()\b0 , \b processor_assign()\b0 , \b task_assign()\b0 , \b thread_assign()\
  2434. \fs20 \
  2435. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  2436. \fs28 processor_set_max_priority()\
  2437. \fs20 \
  2438. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  2439. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Set the maximum priority permitted on a processor set\
  2440. \fs28 \
  2441. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  2442. \fs10 \
  2443. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b processor_set_max_priority(\b0 processor_set_t \i processor_set\i0 , int \i max_priority\i0 , boolean_t \i change_threads\b \i0 )\
  2444. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  2445. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 This function affects only newly created or newly assigned threads unless you specify \i change_threads\i0  as true.\
  2446. \fs20 \
  2447. \fs28 \pard \s37 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Note:  \b0 \fs28 \f1 This function is useful only on multiprocessor systems.  \
  2448. \fs20 \
  2449. \fs28 \s20 \f0 \b \fs28 \fs60 \
  2450. \fs28 processor_set_policy_enable(), processor_set_policy_disable()\
  2451. \fs20 \
  2452. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  2453. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Enable or disable a scheduling policy on a processor set\
  2454. \fs28 \
  2455. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  2456. \fs10 \
  2457. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b processor_set_policy_enable(\b0 processor_set_t \i processor_set\i0 , int \i policy\b \i0 )\
  2458. \b0 kern_return_t \b processor_set_policy_disable(\b0 processor_set_t \i processor_set\i0 , int \i policy\i0 , boolean_t \i change_threads\b \i0 )\
  2459. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  2460. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i processor_set\i0 :  The processor set whose allowed policies are to be changed.  This must be the privileged processor set port, which is returned by \b host_processor_set_priv()\b0 .\
  2461. \fs20 \
  2462. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i policy\i0 :  The policy to enable or disable.  Currently, the only valid policies are POLICY_TIMESHARE, POLICY_INTERACTIVE, and POLICY_FIXEDPRI.  You can\'27t disable timesharing.\
  2463. \fs20 \
  2464. \fs28 \i change_threads\i0 :  Specify true if you want to reset to timesharing the policies of any threads with the newly disallowed policy.  Otherwise, specify false.\
  2465. \fs20 \
  2466. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2467. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 Processor sets may restrict the scheduling policies to be used for threads assigned to them.  These two calls provide the mechanism for designating permitted and forbidden policies.  The current set of permitted policies can be obtained from \b processor_set_info()\b0 .  Timesharing can\'27t be forbidden by any processor set.  This is a compromise to reduce the complexity of the assign operation; any thread whose policy is forbidden by the target processor set has its policy reset to timesharing.  If the \i change_threads\i0  argument to \b processor_set_policy_disable()\b0  is true, threads currently assigned to this processor set and using the newly disabled policy will have their policy reset to timesharing.\
  2468. \fs20 \
  2469. \fs28 \pard \s48 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Warning:  \b0 \fs28 \f1 Don\'27t use POLICY_FIXEDPRI unless you\'27re familiar with the consequences of fixed-priority scheduling.  Using fixed-priority scheduling in a process can keep other processes from getting any CPU time.  If processes that are essential to the functioning of the system don\'27t get CPU time, you might have to reboot your system to make it work normally.\
  2470. \fs20 \
  2471. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  2472. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 kern_return_t    error;\
  2473. \fi0 processor_set_t  default_set, default_set_priv;\
  2474. \pard \s14 \li2116 \fi0 \ri503 \ql \
  2475. error=processor_set_default(host_self(), &default_set);\
  2476. \fi0 if (error!=KERN_SUCCESS) \{\
  2477. \fi0     mach_error("Error calling processor_set_default()", error);\
  2478. \fi0     exit(1);\
  2479. \fi0 \}\
  2480. \fi0 \
  2481. error=host_processor_set_priv(host_priv_self(), default_set,\
  2482. \fi0     &default_set_priv);\
  2483. \fi0 if (error != KERN_SUCCESS) \{\
  2484. \fi0     mach_error("Call to host_processor_set_priv() failed", error);\
  2485. \fi0     exit(1);\
  2486. \fi0 \}\
  2487. \fi0 \
  2488. error=processor_set_policy_enable(default_set_priv, POLICY_FIXEDPRI);\
  2489. \fi0 if (error != KERN_SUCCESS)\
  2490. \fi0     mach_error("Error calling processor_set_policy_enable", error);\
  2491. \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  2492. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  Operation completed successfully.\
  2493. \fs20 \
  2494. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i processor_set\i0  isn\'27t the privileged port of a processor set, \i policy\i0  isn\'27t a valid policy, or an attempt was made to disable timesharing.\
  2495. \fs20 \
  2496. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2497. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b thread_policy()\b0 , \b thread_switch()\
  2498. \fs20 \
  2499. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  2500. \fs28 processor_set_tasks() \
  2501. \fs20 \
  2502. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  2503. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get kernel ports for tasks assigned to a processor set\
  2504. \fs28 \
  2505. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  2506. \fs10 \
  2507. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b processor_set_tasks(\b0 processor_set_t \i processor_set\i0 , task_array_t *\i task_list\i0 , unsigned int *\i task_count\b \i0 )\
  2508. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  2509. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i processor_set\i0 :  The processor set to be affected.  This must be the privileged processor set port, which is returned by \b host_processor_set_priv()\b0 .\
  2510. \fs20 \
  2511. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i task_list\i0 :  Returns the set of tasks currently assigned to \i processor_set\i0 ; no particular ordering is guaranteed.\
  2512. \fs20 \
  2513. \fs28 \i task_count\i0 :  Returns the number of tasks in \i task_list\i0 .\
  2514. \fs20 \
  2515. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2516. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 This function gets send rights to the kernel port for each task currently assigned to \i processor_set\i0 .  The \i task_list\i0  argument is an array that is created as a result of this call.  You should call \b vm_deallocate()\b0  on this array when you no longer need the data.\
  2517. \fs20 \
  2518. \fs28 \s18 \f2 \fs24 \fs10 \
  2519. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 task_array_t    task_list;\
  2520. \fi0 unsigned int    task_count;\
  2521. \fi0 processor_set_t default_set, default_set_priv;\
  2522. \fi0 kern_return_t   error;\
  2523. \pard \s14 \li2116 \fi0 \ri503 \ql \
  2524. error=processor_set_default(host_self(), &default_set);\
  2525. \fi0 if (error!=KERN_SUCCESS) \{\
  2526. \fi0     mach_error("Error calling processor_set_default()", error);\
  2527. \fi0     exit(1);\
  2528. \fi0 \}\
  2529. \fi0 \
  2530. error=host_processor_set_priv(host_priv_self(), default_set,\
  2531. \fi0     &default_set_priv);\
  2532. \fi0 if (error != KERN_SUCCESS) \{\
  2533. \fi0     mach_error("Call to host_processor_set_priv() failed", error);\
  2534. \fi0     exit(1);\
  2535. \fi0 \}\
  2536. \fi0 \
  2537. error=processor_set_tasks(default_set_priv, &task_list, &task_count);\
  2538. \fi0 if (error != KERN_SUCCESS) \{\
  2539. \fi0     mach_error("Call to processor_set_tasks() failed", error); \
  2540. \fi0     exit(1);\
  2541. \fi0 \}\
  2542. \fi0 \
  2543. /* . . . */\
  2544. \fi0 error=vm_deallocate(task_self(), (vm_address_t)task_list, \
  2545. \fi0     sizeof(task_list)*task_count);\
  2546. \fi0 if (error != KERN_SUCCESS)\
  2547. \fi0     mach_error("Trouble freeing task_list", error);\
  2548. \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  2549. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  2550. \fs20 \
  2551. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i processor_set\i0  isn\'27t a privileged processor set.\
  2552. \fs20 \
  2553. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2554. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b task_assign()\b0 , \b thread_assign()\b0 , \b processor_set_threads()\
  2555. \fs20 \
  2556. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  2557. \fs28 processor_set_threads() \
  2558. \fs20 \
  2559. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  2560. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get kernel ports for threads assigned to a processor set\
  2561. \fs28 \
  2562. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  2563. \fs10 \
  2564. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b processor_set_threads(\b0 processor_set_t \i processor_set\i0 , thread_array_t *\i thread_list\i0 , unsigned int *\i thread_count\b \i0 )\
  2565. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  2566. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i processor_set\i0 :  The processor set to be affected.  This must be the privileged processor set port, which is returned by \b host_processor_set_priv()\b0 .\
  2567. \fs20 \
  2568. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i thread_list\i0 :  Returns the set of threads currently assigned to \i processor_set\i0 ; no particular ordering is guaranteed.\
  2569. \fs20 \
  2570. \fs28 \i thread_count\i0 :  Returns the number of threads in \i thread_list\i0 .\
  2571. \fs20 \
  2572. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2573. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 This function gets send rights to the kernel port for each thread currently assigned to \i processor_set\i0 .  The \i thread_list\i0  argument is an array that is created as a result of this call.  You should call \b vm_deallocate()\b0  on \i thread_list\i0  when you no longer need the data.\
  2574. \fs20 \
  2575. \fs28 \s18 \f2 \fs24 \fs10 \
  2576. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 thread_array_t  thread_list;\
  2577. \fi0 unsigned int    thread_count;\
  2578. \fi0 processor_set_t default_set, default_set_priv;\
  2579. \fi0 kern_return_t   error;\
  2580. \pard \s14 \li2116 \fi0 \ri503 \ql \
  2581. error=processor_set_default(host_self(), &default_set);\
  2582. \fi0 if (error!=KERN_SUCCESS) \{\
  2583. \fi0     mach_error("Error calling processor_set_default()", error);\
  2584. \fi0     exit(1);\
  2585. \fi0 \}\
  2586. \fi0 \
  2587. error=host_processor_set_priv(host_priv_self(), default_set,\
  2588. \fi0     &default_set_priv);\
  2589. \fi0 if (error != KERN_SUCCESS) \{\
  2590. \fi0     mach_error("Call to host_processor_set_priv() failed", error);\
  2591. \fi0     exit(1);\
  2592. \fi0 \}\
  2593. \fi0 \
  2594. error=processor_set_threads(default_set_priv, &thread_list, &thread_count);\
  2595. \fi0 if (error != KERN_SUCCESS) \{\
  2596. \fi0     mach_error("Call to processor_set_threads() failed", error); \
  2597. \fi0     exit(1);\
  2598. \fi0 \}\
  2599. \fi0 \
  2600. /* . . . */\
  2601. \fi0 error=vm_deallocate(task_self(), (vm_address_t)thread_list, \
  2602. \fi0     sizeof(thread_list)*thread_count);\
  2603. \fi0 if (error != KERN_SUCCESS)\
  2604. \fi0     mach_error("Trouble freeing thread_list", error);\
  2605. \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  2606. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  2607. \fs20 \
  2608. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i processor_set\i0  isn\'27t a privileged processor set.\
  2609. \fs20 \
  2610. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2611. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b task_assign()\b0 , \b thread_assign()\b0 , \b processor_set_tasks()\
  2612. \fs20 \
  2613. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  2614. \fs28 task_assign(), task_assign_default()\
  2615. \fs20 \
  2616. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  2617. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Assign a task to a processor set\
  2618. \fs28 \
  2619. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  2620. \fs10 \
  2621. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b task_assign(\b0 task_t \i task\i0 , processor_set_t \i new_processor_set\i0 , boolean_t \i assign_threads\b \i0 )\
  2622. \b0 kern_return_t \b task_assign_default(\b0 task_t \i task\i0 , boolean_t \i assign_threads\b \i0 )\
  2623. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  2624. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The \b task_assign()\b0  function assigns \i task\i0  to \i new_processor_set\i0 ; \b task_assign_default()\b0  assigns \i task\i0  to the default processor set.\
  2625. \fs20 \
  2626. \fs28 \pard \s37 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Note:  \b0 \fs28 \f1 These functions are useful only on multiprocessor systems.  \
  2627. \fs20 \
  2628. \fs28 \s20 \f0 \b \fs28 \fs60 \
  2629. \fs28 task_by_unix_pid()\
  2630. \fs20 \
  2631. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  2632. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get the task port for a UNIX process on the same host\
  2633. \fs28 \
  2634. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  2635. \fs10 \
  2636. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b task_by_unix_pid(\b0 task_t \i task\i0 , int \i pid\i0 , task_t *\i result_task\b \i0 )\
  2637. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  2638. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i task\i0 :  A task that is used to check permission (usually \b task_self()\b0 ).\
  2639. \fs20 \
  2640. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i pid\i0 :  The process ID of the desired process.\
  2641. \fs20 \
  2642. \fs28 \i result_task\i0 :  Returns send rights to the task port of the process specified by \i pid\i0 .  \
  2643. \fs20 \
  2644. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2645. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 Returns the task port for another process, named by its process ID, on the same host as \i task\i0 .  This call succeeds only if the caller is the superuser or \i task\i0  has the same user ID as the process specified by \i pid\i0 .  If the call fails, \i result_task\i0  is set to TASK_NULL.\
  2646. \fs20 \
  2647. \fs28 \s18 \f2 \fs24 \fs10 \
  2648. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 pid=fork();\
  2649. \fi0     \
  2650. \fi0 if (pid==0) /* We\'27re in the child. */ \{\
  2651. \fi0     /* do childish things */\
  2652. \fi0 \}\
  2653. \fi0 else /* We\'27re in the parent */ \{\
  2654. \fi0     result=task_by_unix_pid(task_self(), pid, &child_task);\
  2655. \fi0     if (result != KERN_SUCCESS)\
  2656. \fi0         mach_error("task_by_unix_pid", result);\
  2657. \fi0     /* . . . */\
  2658. \fi0 \}\
  2659. \s25 \fi-2015 \f1 \fs28 \fs28 \
  2660. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  2661. \fs20 \
  2662. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_FAILURE:  \i target_task\i0  has a different user ID from the process corresponding to \i pid,\i0  and the caller\i  \i0 isn\'27t the superuser; or \i pid\i0  didn\'27t refer to a valid process; or \i target_task\i0  wasn\'27t a valid task.\
  2663. \fs20 \
  2664. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b \fs10 \
  2665. \fs28 \f0 \fs20     SEE ALSO    \fs28 \f1 unix_pid()\
  2666. \fs20 \
  2667. \fs28 \s20 \fi0 \f0 \fs28 \fs60 \
  2668. \fs28 task_create()\
  2669. \fs20 \
  2670. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  2671. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Create a task\
  2672. \fs28 \
  2673. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  2674. \fs10 \
  2675. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b task_create(\b0 task_t \i parent_task\i0 , boolean_t \i inherit_memory\i0 , task_t *\i child_task\b \i0 )\
  2676. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  2677. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i parent_task\i0 :  The task from which the child\'27s capabilities are drawn.\
  2678. \fs20 \
  2679. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i inherit_memory\i0 :  If set, the address space of the child task is built from the parent task according to its memory inheritance values; otherwise, the child task is given an empty address space.\
  2680. \fs20 \
  2681. \fs28 \i child_task\i0 :  Returns the new task.\
  2682. \fs20 \
  2683. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2684. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b task_create()\b0  creates a new task from \i parent_task\i0 ; the resulting task (\i child_task\i0 ) acquires shared or copied parts of the parent\'27s address space (see \b vm_inherit()\b0 ).  The child task initially has no threads; you put threads in it using \b thread_create()\b0 .  \
  2685. \fs20 \
  2686. \fs28 \pard \s36 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Important:  \b0 \fs28 \f1 Normally, you should use the UNIX \b fork()\b0  system call instead of \b task_create()\b0 .\
  2687. \fs20 \
  2688. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The child task gets the four special ports initialized for it at task creation.  The kernel port (task port) is created, and send rights for it are given to the child and returned to the caller in \i child_task\i0 .  The notify port is initialized to null.  The child inherits its bootstrap and exception ports from the parent task.  The new task can get send rights to these ports with the call \b task_get_special_port()\b0 .\
  2689. \fs20 \
  2690. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  2691. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 error=task_create(task_self(), TRUE, &child_task);\
  2692. \fi0 if(error!=KERN_SUCCESS)\
  2693. \fi0     mach_error("Call to task_create() failed", error);\
  2694. \s25 \fi-2015 \f1 \fs28 \fs28 \
  2695. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  A new task has been created.\
  2696. \fs20 \
  2697. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i parent_task\i0  is not a valid task port.  \
  2698. \fs20 \
  2699. \fs28 KERN_RESOURCE_SHORTAGE:  Some critical kernel resource is unavailable.  \
  2700. \fs20 \
  2701. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2702. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b task_terminate()\b0 , \b task_suspend()\b0 , \b task_resume()\b0 , \b task_get_special_port()\b0 ,\b  task_set_special_port()\b0 ,\b  task_self()\b0 , \b task_threads()\b0 , \b thread_create()\b0 , \b thread_resume()\b0 , \b vm_inherit()\
  2703. \fs20 \
  2704. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  2705. \fs28 task_get_assignment()\
  2706. \fs20 \
  2707. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  2708. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get the name of the processor set that a task is assigned to\
  2709. \fs28 \
  2710. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  2711. \fs10 \
  2712. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b task_get_assignment(\b0 task_t \i task\i0 , processor_set_t *\i processor_set\b \i0 )\
  2713. \s37 \li2116 \fi0 \b0 \fs20 \
  2714. \fs28 \f0 \b \fs28 Note:  \b0 \fs28 \f1 This function is useful only on multiprocessor systems.  \
  2715. \fs20 \
  2716. \fs28 \s20 \f0 \b \fs28 \fs60 \
  2717. \fs28 task_get_special_port(), task_set_special_port(), task_self(), task_notify()\
  2718. \fs20 \
  2719. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  2720. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get or set a task\'27s special ports\
  2721. \fs28 \
  2722. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  2723. \fs10 \
  2724. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b task_get_special_port(\b0 task_t \i task\i0 , int \i which_port\i0 , port_t *\i special_port\b \i0 )\
  2725. \b0 kern_return_t \b task_set_special_port(\b0 task_t \i task\i0 , int \i which_port\i0 , port_t \i special_port\b \i0 )\
  2726. \b0 task_t \b task_self(\b0 void\b )\
  2727. \b0 port_t \b task_notify(\b0 void\b )\
  2728. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  2729. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i task\i0 :  The task to get the port for.\
  2730. \fs20 \
  2731. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i which_port\i0 :  The port that\'27s requested.  This is one of:\
  2732. \fs20 \
  2733. \fs28 \pard \s44 \li2494 \fi0 \ri1007 \ql \tx6148 \tx10180 TASK_NOTIFY_PORT\
  2734. \fi0 TASK_BOOTSTRAP_PORT\
  2735. \fi0 TASK_EXCEPTION_PORT\
  2736. \fs20 \
  2737. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i special_port\i0 :  The value of the port that\'27s being requested or set.\
  2738. \fs20 \
  2739. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2740. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b task_get_special_port()\b0  returns send rights to one of a set of special ports for the task specified by \i task.  \i0 In the case of the task\'27s own notify port, the task also gets receive rights.\
  2741. \fs20 \
  2742. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The function \b task_set_special_port()\b0  sets one of a set of special ports for the task specified by \i task\i0 .\
  2743. \fs20 \
  2744. \fs28 The function \b task_self()\b0  returns the port to which kernel calls for the currently executing thread should be directed.  Currently, \b task_self()\b0  returns the task kernel port, which is a port for which the kernel has receive rights and which it uses to identify a task.  In the future it may be possible for one task to interpose a port as another task\'27s kernel port.  At that time \b task_self()\b0  will still return the port to which the executing thread should direct kernel calls, but it may no longer be a port for which the kernel has receive rights.\
  2745. \fs20 \
  2746. \fs28 If a controller task has send access to the kernel port of a subject task, then the controller task can perform kernel operations for the subject task.  Normally, only the task itself and the task that created it will have access to the task kernel port, but any task may pass rights to its kernel port to any other task.\
  2747. \fs20 \
  2748. \fs28 The function \b task_notify()\b0  returns receive and send rights to the notify port associated with the task to which the executing thread belongs.  The notify port is a port on which the task should receive notification of such kernel events as the destruction of a port to which it has send rights.\
  2749. \fs20 \
  2750. \fs28 The other special ports associated with a task are the bootstrap port and the exception port.  The bootstrap port is a port to which a thread may send a message requesting other system service ports.  This port isn\'27t used by the kernel.  The task\'27s exception port is the port to which messages are sent by the kernel when an exception occurs and the thread causing the exception has no exception port of its own.\
  2751. \fs20 \
  2752. \fs28 \pard \s36 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Important:  \b0 \fs28 \f1 If you set your task\'27s bootstrap port, you should also set the global variable \b bootstrap_port\b0  to \i special_port\i0 .  The \b bootstrap_port\b0  variable is task-wide and is used by \b mach_init\b0  and other processes to determine your task\'27s bootstrap port.  Since you can\'27t change the value of the \b bootstrap_port\b0  variable in another task, you should use care when changing the bootstrap port of another task.  \
  2753. \fs20 \
  2754. \fs28 \pard \s24 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f0 \b \fs20 \fs10 \
  2755. \fs20     MACRO    \
  2756. \s17 \f1 \b0 \fs28 \f0 \b \fs20     EQUIVALENTS    \b0 \fs28 \f1 The following macros are defined in the header file \b mach/task_special_ports.h\b0 :\
  2757. \fs20 \
  2758. \fs28 \pard \s44 \li2494 \fi0 \ri1007 \ql \tx6148 \tx10180 \b task_get_notify_port(\b0 \i task\i0 , \i port\b \i0 )\
  2759. \fi0 task_set_notify_port(\b0 \i task\i0 , \i port\b \i0 )\
  2760. \fs20 \
  2761. \fs28 \fi0 \b0 \b task_get_exception_port(\b0 \i task\i0 , \i port\b \i0 )\
  2762. \fi0 task_set_exception_port(\b0 \i task\i0 , \i port\b \i0 )\
  2763. \fs20 \
  2764. \fs28 \fi0 \b0 \b task_get_bootstrap_port(\b0 \i task\i0 , \i port\b \i0 )\
  2765. \fi0 task_set_bootstrap_port(\b0 \i task\i0 , \i port\b \i0 )\
  2766. \fs20 \
  2767. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \b0 \fs24 \fs10 \
  2768. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 /* Save the old exception port for this task. */\
  2769. \fi0 r = task_get_exception_port(task_self(), &(ports.old_exc_port));\
  2770. \fi0 if (r != KERN_SUCCESS) \{\
  2771. \fi0     mach_error("task_get_exception_port", r);\
  2772. \fi0     exit(1);\
  2773. \fi0 \} \
  2774. \pard \s14 \li2116 \fi0 \ri503 \ql \
  2775.     /* Create a new exception port for this task. */\
  2776. \fi0 r = port_allocate(task_self(), &(ports.exc_port));\
  2777. \fi0 if (r != KERN_SUCCESS) \{\
  2778. \fi0     mach_error("port_allocate 0", r);\
  2779. \fi0     exit(1);\
  2780. \fi0 \}\
  2781. \fi0 r = task_set_exception_port(task_self(), (ports.exc_port));\
  2782. \fi0 if (r != KERN_SUCCESS) \{\
  2783. \fi0     mach_error("task_set_exception_port", r);\
  2784. \fi0     exit(1);\
  2785. \fi0 \}\
  2786. \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  2787. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The port was returned or set.\
  2788. \fs20 \
  2789. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  Either \i task\i0  is not a task or \i which_port\i0  is an invalid port selector.\
  2790. \fs20 \
  2791. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2792. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b thread_special_ports()\b0 , \b task_create()\
  2793. \fs20 \
  2794. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  2795. \fs28 task_info()\
  2796. \fs20 \
  2797. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  2798. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get information about a task\
  2799. \fs28 \
  2800. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  2801. \fs10 \
  2802. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b task_info(\b0 task_t \i target_task\i0 , int \i flavor\i0 , task_info_t \i task_info\i0 , unsigned int *\i task_info_count\b \i0 )\
  2803. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  2804. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i target_task\i0 :  The task to be affected (for example, use \b task_self()\b0  to specify the caller\'27s task).\
  2805. \fs20 \
  2806. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i flavor\i0 :  The type of statistics that are wanted.  Currently only TASK_BASIC_INFO is implemented.\
  2807. \fs20 \
  2808. \fs28 \i task_info\i0 :  Returns statistics about \i target_task\i0 .\
  2809. \fs20 \
  2810. \fs28 \i task_info_count\i0 :  Size of the info structure.  Currently this must be TASK_BASIC_INFO_COUNT.\
  2811. \fs20 \
  2812. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2813. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b task_info()\b0  returns the information specified by \i flavor\i0  about a task\i .  \i0 The \i task_info\i0  argument is an array of integers that\'27s supplied by the caller and returned filled with information.  The \i task_info_count\i0  argument is supplied as the maximum number of integers in \i task_info.  \i0 On return, it contains the actual number of integers in \i task_info\i0 .\
  2814. \fs20 \
  2815. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Currently there\'27s only one flavor of information, defined by TASK_BASIC_INFO.  Its size is defined by TASK_BASIC_INFO_COUNT.  The definition of the information structure returned by TASK_BASIC_INFO is:\
  2816. \fs20 \
  2817. \fs28 \pard \s12 \li2494 \fi0 \ri1007 \ql \f2 \fs24 struct task_basic_info \{\
  2818. \fi0     int           suspend_count;  /* suspend count for task */\
  2819. \fi0     int           base_priority;  /* base scheduling priority */\
  2820. \fi0     vm_size_t     virtual_size;   /* number of virtual pages */\
  2821. \fi0     vm_size_t     resident_size;  /* number of resident pages */\
  2822. \fi0     time_value_t  user_time;      /* total user run time for \
  2823. \fi0                                      terminated threads */\
  2824. \fi0     time_value_t  system_time;    /* total system run time for \
  2825. \fi0                                      terminated threads */\
  2826. \fi0 \};\
  2827. \fi0 typedef struct task_basic_info  *task_basic_info_t;\
  2828. \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs28 \
  2829. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 kern_return_t             error;\
  2830. \fi0 struct task_basic_info    info;\
  2831. \fi0 unsigned int              info_count=TASK_BASIC_INFO_COUNT;\
  2832. \fi0 \
  2833. \fi0 error=task_info(task_self(), TASK_BASIC_INFO, \
  2834. \fi0     (task_info_t)&info, &info_count);\
  2835. \fi0 if (error!=KERN_SUCCESS)\
  2836. \fi0     mach_error("Error calling task_info()", error);\
  2837. \fi0 else\
  2838. \fi0     printf("Base priority is %d\\n", info.base_priority);\
  2839. \s25 \fi-2015 \f1 \fs28 \fs28 \
  2840. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  2841. \fs20 \
  2842. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i target_task\i0  isn\'27t a task, or \i flavor\i0  isn\'27t recognized.\
  2843. \fs20 \
  2844. \fs28 MIG_ARRAY_TOO_LARGE:  The returned info array is too large for \i task_info\i0 .  The \i task_info\i0  argument is filled as much as possible, and \i task_info_count\i0  is set to the number of elements that would be returned if there were enough room.\
  2845. \fs20 \
  2846. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2847. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b task_threads()\b0 , \b thread_info()\b0 , \b thread_get_state()\
  2848. \fs20 \
  2849. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  2850. \fs28 task_priority() \
  2851. \fs20 \
  2852. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  2853. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Set the scheduling priority for a task\
  2854. \fs28 \
  2855. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  2856. \fs10 \
  2857. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b task_priority(\b0 task_t \i task\i0 , int \i priority\i0 , boolean_t \i change_threads\b \i0 )\
  2858. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  2859. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i task\i0 :  Task to set priority for.\
  2860. \fs20 \
  2861. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i priority\i0 :  New priority.\
  2862. \fs20 \
  2863. \fs28 \i change_threads\i0 :  Change priority of existing threads if true.  \
  2864. \fs20 \
  2865. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2866. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The priority of a task is used only for creation of new threads; the priority of a new thread priority is set to that of its task.  The \b task_priority()\b0  function changes this task priority.  It also sets the priorities of all threads in the task to this new priority if \i change_threads\i0  is true.  Existing threads are not affected otherwise.  If this priority change violates the maximum priority of some threads, as many threads as possible will be changed and an error code will be returned.\
  2867. \fs20 \
  2868. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Priorities range from 0 to 31, where higher numbers denote higher priorities.  You can retrieve the current scheduling priority using \b thread_info()\b0 .\
  2869. \fs20 \
  2870. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  2871. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 kern_return_t             error;\
  2872. \fi0 struct task_basic_info    info;\
  2873. \fi0 unsigned int              info_count=TASK_BASIC_INFO_COUNT;\
  2874. \fi0 \
  2875. \fi0 error=task_info(task_self(), TASK_BASIC_INFO, \
  2876. \fi0     (task_info_t)&info, &info_count);\
  2877. \fi0 if (error!=KERN_SUCCESS) \
  2878. \fi0     mach_error("Error calling task_info()", error);\
  2879. \fi0 else \{\
  2880. \fi0     /* Set this task\'27s base priority to be much lower than normal */\
  2881. \fi0     error = task_priority(task_self(), info.base_priority - 4, TRUE);\
  2882. \fi0     if (error != KERN_SUCCESS)\
  2883. \fi0         mach_error("Call to task_priority() failed", error);\
  2884. \fi0 \}\
  2885. \s25 \fi-2015 \f1 \fs28 \fs28 \
  2886. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  2887. \fs20 \
  2888. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i task\i0  is not a task, or \i priority\i0  is not a valid priority.\
  2889. \fs20 \
  2890. \fs28 KERN_FAILURE:  \i change_threads\b \i0  \b0 was true and the attempt to change the priority of at least one existing thread failed because the new priority would have exceeded that thread\'27s maximum priority.\
  2891. \fs20 \
  2892. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2893. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b thread_priority()\b0 , \b processor_set_max_priority()\b0 , \b thread_switch()\
  2894. \fs20 \
  2895. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  2896. \fs28 task_resume()\
  2897. \fs20 \
  2898. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  2899. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Resume a task\
  2900. \fs28 \
  2901. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  2902. \fs10 \
  2903. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b task_resume(\b0 task_t \i target_task\b \i0 )\
  2904. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  2905. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i target_task\i0 :  The task to be resumed.\
  2906. \fs20 \
  2907. \fs28 \s16 \fs10 \
  2908. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b task_resume()\b0  decrements the task\'27s suspend count.  If the suspend count becomes 0, all threads with 0 suspend counts in the task are resumed.  If the suspend count is already 0, it\'27s not decremented (it never becomes negative).\
  2909. \fs20 \
  2910. \fs28 \s25 \fs10 \
  2911. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The task has been resumed.\
  2912. \fs20 \
  2913. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_FAILURE:  The suspend count is already 0.\
  2914. \fs20 \
  2915. \fs28 KERN_INVALID_ARGUMENT:  \i target_task\i0  isn\'27t a task.\
  2916. \fs20 \
  2917. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2918. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b task_create()\b0 , \b task_terminate()\b0 , \b task_suspend()\b0 , \b task_info()\b0 , \b thread_suspend()\b0 , \b thread_resume()\b0 , \b thread_info()\
  2919. \fs20 \
  2920. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  2921. \fs28 task_suspend()\
  2922. \fs20 \
  2923. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  2924. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Suspend a task\
  2925. \fs28 \
  2926. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  2927. \fs10 \
  2928. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b task_suspend(\b0 task_t \i target_task\b \i0 )\
  2929. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  2930. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i target_task\i0 :  The task to be suspended (for example, use \b task_self()\b0  to specify the caller\'27s task).\
  2931. \fs20 \
  2932. \fs28 \s16 \fs10 \
  2933. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b task_suspend()\b0  increments the task\'27s suspend count and stops all threads in the task.  As long as the suspend count is positive, newly created threads will not run.  This call doesn\'27t return until all threads are suspended.\
  2934. \fs20 \
  2935. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 If the count becomes greater than 1, it will take more than one \b task_resume()\b0  call to restart the task.\
  2936. \fs20 \
  2937. \fs28 \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2938. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The task has been suspended.\
  2939. \fs20 \
  2940. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i target_task\i0  isn\'27t a task.\
  2941. \fs20 \
  2942. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2943. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b task_create()\b0 , \b task_terminate()\b0 , \b task_resume()\b0 , \b task_info()\b0 , \b thread_suspend()\
  2944. \fs20 \
  2945. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  2946. \fs28 task_terminate()\
  2947. \fs20 \
  2948. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  2949. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Terminate a task\
  2950. \fs28 \
  2951. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  2952. \fs10 \
  2953. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b task_terminate(\b0 task_t \i target_task\b \i0 )\
  2954. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  2955. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i target_task\i0 :  The task to be destroyed (for example, use \b task_self()\b0  to specify the caller\'27s task).\
  2956. \fs20 \
  2957. \fs28 \s16 \fs10 \
  2958. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b task_terminate()\b0  destroys the task specified by \i target_task\i0  and all its threads.  All resources that are used only by this task are freed.  Any port to which this task has receive rights is destroyed.\
  2959. \fs20 \
  2960. \fs28 \s25 \fs10 \
  2961. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The task has been destroyed.\
  2962. \fs20 \
  2963. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i target_task\i0  isn\'27t a task.\
  2964. \fs20 \
  2965. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2966. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b task_create()\b0 , \b task_suspend()\b0 , \b task_resume()\b0 , \b thread_terminate()\b0 , \b thread_suspend()\
  2967. \fs20 \
  2968. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  2969. \fs28 task_threads()\
  2970. \fs20 \
  2971. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  2972. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get a task\'27s threads\
  2973. \fs28 \
  2974. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  2975. \fs10 \
  2976. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b task_threads(\b0 task_t \i target_task\i0 , thread_array_t *\i thread_list\i0 , unsigned int *\i thread_count\b \i0 )\
  2977. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  2978. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i target_task\i0 :  The task to be affected (for example, use \b task_self()\b0  to specify the caller\'27s task).\
  2979. \fs20 \
  2980. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i thread_list\i0 :  Returns the set of threads contained within \i target_task\i0 ; no particular ordering is guaranteed.\
  2981. \fs20 \
  2982. \fs28 \i thread_count\i0 :  Returns the number of threads in \i thread_list\i0 .\
  2983. \fs20 \
  2984. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  2985. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b task_threads()\b0  gets send rights to the kernel port for each thread contained in \i target_task\i0 .\
  2986. \fs20 \
  2987. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The array \i thread_list\i0  is created as a result of this call.  You should call \b vm_deallocate()\b0  on this array when the data is no longer needed.\
  2988. \fs20 \
  2989. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  2990. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 r = task_threads(task_self(), &thread_list, &thread_count);\
  2991. \fi0 if (r != KERN_SUCCESS)\
  2992. \fi0     mach_error("Error calling task_threads", r);\
  2993. \fi0 else \{\
  2994. \fi0     if (thread_count == 1) \
  2995. \fi0         printf ("There\'27s 1 thread in this task\\n");\
  2996. \fi0     else\
  2997. \fi0         printf("There are %d threads in this task\\n", thread_count);\
  2998. \fi0 \
  2999. \pard \s14 \li2116 \fi0 \ri503 \ql /* Deallocate the list of threads. */\
  3000. \fi0     r = vm_deallocate(task_self(), (vm_address_t)thread_list, \
  3001. \fi0         sizeof(thread_list)*thread_count);\
  3002. \fi0     if (r != KERN_SUCCESS)\
  3003. \fi0         mach_error("Trouble freeing thread_list", r);\
  3004. \fi0 \}\
  3005. \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  3006. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  3007. \fs20 \
  3008. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i target_task\i0  isn\'27t a task.\
  3009. \fs20 \
  3010. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3011. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b thread_create()\b0 , \b thread_terminate()\b0 , \b thread_suspend()\
  3012. \fs20 \
  3013. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  3014. \fs28 thread_abort()\
  3015. \fs20 \
  3016. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  3017. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Interrupt a thread\
  3018. \fs28 \
  3019. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  3020. \fs10 \
  3021. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b thread_abort(\b0 thread_t \i target_thread\b \i0 )\
  3022. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  3023. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i target_thread\i0 :  The thread to be interrupted.\
  3024. \fs20 \
  3025. \fs28 \s16 \fs10 \
  3026. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b thread_abort()\b0  aborts page faults and the kernel functions \b msg_send()\b0 , \b msg_receive()\b0 , and \b msg_rpc()\b0 , making the call return a code indicating that it was interrupted.  The call is interrupted whether or not the thread (or task containing it) is currently suspended.  If it\'27s suspended, the thread receives the interrupt when it resumes.\
  3027. \fs20 \
  3028. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 A thread will retry an aborted page fault if its state isn\'27t modified before it resumes.  The function \b msg_send()\b0  returns SEND_INTERRUPTED; \b msg_receive()\b0  returns RCV_INTERRUPTED; and \b msg_rpc()\b0  returns either SEND_INTERRUPTED or RCV_INTERRUPTED, depending on which half of the RPC was interrupted.\
  3029. \fs20 \
  3030. \fs28 This function lets one thread stop another thread cleanly, thereby allowing the future execution of the target thread to be controlled in a predictable way.  The \b thread_suspend()\b0  function keeps the target thread from executing any further instructions at the user level, including the return from a system call.  The \b thread_get_state()\b0  and \b thread_set_state()\b0  functions let you examine or modify the user state of a target thread.  However, if a suspended thread was executing within a system call, it also has associated with it a kernel state.  This kernel state can\'27t be modified by \b thread_set_state()\b0 ; therefore, when the thread is resumed the system call may return, changing the user state and possibly user memory.\
  3031. \fs20 \
  3032. \fs28 The \b thread_abort()\b0  function aborts the kernel call from the target thread\'27s point of view by resetting the kernel state so that the thread will resume execution just after the system call.  The system call will return one of the interrupted codes described previously.  The system call will either be entirely completed or entirely aborted, depending on the precise moment at which the abort was received.  Thus if the thread\'27s user state has been changed by \b thread_set_state()\b0 , it won\'27t be modified by any unexpected system call side effects.\
  3033. \fs20 \
  3034. \fs28 For example, to simulate a UNIX signal, the following sequence of calls may be used:\
  3035. \fs20 \
  3036. \fs28 \s38 \li2494 \fi-378 \f0 \fs28 1.    \fs28 \f1 \b thread_suspend()\b0 \'d0Stops the thread.\
  3037. \fs20 \
  3038. \fs28 \s40 \f0 \fs28 2.    \fs28 \f1 \b thread_abort()\b0 \'d0Interrupts any system call in progress, setting the return value to \'aainterrupted.\'ba  Since the thread is stopped, it won\'27t return to user code.\
  3039. \fs20 \
  3040. \fs28 \f0 \fs28 3.    \fs28 \f1 \b thread_set_state()\b0 \'d0Alters the thread\'27s state to simulate a procedure call to the signal handler.\
  3041. \fs20 \
  3042. \fs28 \f0 \fs28 4.    \fs28 \f1 \b thread_resume()\b0 \'d0Resumes execution at the signal handler.  If the thread\'27s stack has been correctly set up, the thread can return to the interrupted system call.\
  3043. \fs20 \
  3044. \fs28 \s4 \li2116 \fi0 Calling \b thread_abort()\b0  on a thread that\'27s not suspended is risky, since it\'27s difficult to know exactly what system trap, if any, the thread might be executing and whether an interrupt return would cause the thread to do something useful.\
  3045. \fs20 \
  3046. \fs28 \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3047. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The thread received an interrupt.\
  3048. \fs20 \
  3049. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i target_thread\i0  isn\'27t a thread.\
  3050. \fs20 \
  3051. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3052. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b thread_get_state()\b0 , \b thread_info()\b0 , \b thread_terminate()\b0 , \b thread_suspend()\
  3053. \fs20 \
  3054. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  3055. \fs28 thread_assign(), thread_assign_default()\
  3056. \fs20 \
  3057. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  3058. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Assign a thread to a processor set\
  3059. \fs28 \
  3060. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  3061. \fs10 \
  3062. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b thread_assign(\b0 thread_t \i thread\i0 , processor_set_t \i new_processor_set\b \i0 )\
  3063. \b0 kern_return_t \b thread_assign_default(\b0 thread_t \i thread\b \i0 )\
  3064. \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  3065. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 \b thread_assign()\b0  assigns \i thread\i0  to \i new_processor_set\i0 ; \b thread_assign_default()\b0  assigns \i thread\i0  to the default processor set.\
  3066. \fs20 \
  3067. \fs28 \pard \s37 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Note:  \b0 \fs28 \f1 These functions are useful only on multiprocessor systems.  \
  3068. \fs20 \
  3069. \fs28 \s20 \f0 \b \fs28 \fs60 \
  3070. \fs28 thread_create() \
  3071. \fs20 \
  3072. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  3073. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Create a thread\
  3074. \fs28 \
  3075. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  3076. \fs10 \
  3077. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b thread_create(\b0 task_t \i parent_task\i0 , thread_t *\i child_thread\b \i0 )\
  3078. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  3079. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i parent_task\i0 :  The task that should contain the new thread.\
  3080. \fs20 \
  3081. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i child_thread\i0 :  Returns the new thread.\
  3082. \fs20 \
  3083. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3084. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b thread_create()\b0  creates a new thread within \i parent_task.  \i0 The new thread has no processor state, and has a suspend count of 1.  To get a new thread to run, first call \b thread_create()\b0  to get the new thread\'27s identifier, \i child_thread.  \i0 Then call \b thread_set_state()\b0  to set a processor state.  Finally, call \b thread_resume()\b0  to schedule the thread to execute.\
  3085. \fs20 \
  3086. \fs28 \pard \s36 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Important:  \b0 \fs28 \f1 Don\'27t use this function unless you\'27re writing a loadable kernel server or implementing a new thread package, such as the C-thread functions.  For normal, user-level programming, use \b cthread_fork()\b0  instead.  You can then use \b cthread_thread()\b0  if you need to get the Mach thread that corresponds to the new C-thread.  \
  3087. \fs20 \
  3088. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 When the thread is created, send rights to its thread kernel port are given to it and returned to the caller in \i child_thread.  \i0 The new thread\'27s exception port is set to PORT_NULL.\
  3089. \fs20 \
  3090. \fs28 \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3091. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  A new thread has been created.\
  3092. \fs20 \
  3093. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i parent_task\i0  isn\'27t a valid task.\
  3094. \fs20 \
  3095. \fs28 KERN_RESOURCE_SHORTAGE:  Some critical kernel resource isn\'27t available.\
  3096. \fs20 \
  3097. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3098. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b task_create()\b0 , \b task_threads()\b0 , \b thread_terminate()\b0 , \b thread_suspend()\b0 , \b thread_resume()\b0 , \b thread_special_ports()\b0 , \b thread_set_state()\
  3099. \fs20 \
  3100. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  3101. \fs28 thread_get_assignment()\
  3102. \fs20 \
  3103. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  3104. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get the name of the processor set to which a thread is assigned\
  3105. \fs28 \
  3106. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  3107. \fs10 \
  3108. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b thread_get_assignment(\b0 thread_t \i thread\i0 , processor_set_t *\i processor_set\b \i0 )\
  3109. \s37 \li2116 \fi0 \b0 \fs20 \
  3110. \fs28 \f0 \b \fs28 Note:  \b0 \fs28 \f1 This function is useful only in multiprocessor systems.  \
  3111. \fs20 \
  3112. \fs28 \s20 \f0 \b \fs28 \fs60 \
  3113. \fs28 thread_get_special_port(), thread_set_special_port(), thread_self(), thread_reply()\
  3114. \fs20 \
  3115. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  3116. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get or set a thread\'27s special ports\
  3117. \fs28 \
  3118. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  3119. \fs10 \
  3120. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b thread_get_special_port(\b0 thread_t \i thread\i0 , int \i which_port\i0 , port_t *\i special_port\b \i0 )\
  3121. \b0 kern_return_t \b thread_set_special_port(\b0 thread_t \i thread\i0 , int \i which_port\i0 , port_t \i special_port\b \i0 )\
  3122. \b0 thread_t \b thread_self(\b0 void\b )\
  3123. \b0 port_t \b thread_reply(\b0 void\b )\
  3124. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  3125. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i thread\i0 :  The thread to get the port for.\
  3126. \fs20 \
  3127. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i which_port\i0 :  The port that\'27s requested.  This is one of:\
  3128. \fs20 \
  3129. \fs28 \pard \s44 \li2494 \fi0 \ri1007 \ql \tx6148 \tx10180 THREAD_REPLY_PORT \
  3130. \fi0 THREAD_EXCEPTION_PORT\
  3131. \fs20 \
  3132. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i special_port\i0 :  The value of the port that\'27s being requested or set.\
  3133. \fs20 \
  3134. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3135. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b thread_get_special_port()\b0  returns send rights to one of a set of special ports for the thread specified by \i thread.  \i0 In the case of getting the thread\'27s own reply port, receive rights are also given to the thread.\
  3136. \fs20 \
  3137. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The function \b thread_set_special_port()\b0  sets one of a set of special ports for the thread specified by \i thread\i0 .\
  3138. \fs20 \
  3139. \fs28 The function \b thread_self()\b0  returns the port to which kernel calls for the currently executing thread should be directed.  Currently \b thread_self()\b0  returns the thread kernel port, which is a port for which the kernel has receive rights and which it uses to identify a thread.  In the future it may be possible for one thread to interpose a port as another thread\'27s kernel port.  At that time \b thread_self()\b0  will still return the port to which the executing thread should direct kernel calls, but it may no longer be a port for which the kernel has receive rights.\
  3140. \fs20 \
  3141. \fs28 If a controller thread has send access to the kernel port of a subject thread, the controller thread can perform kernel operations for the subject thread.  Normally only the thread itself and its parent task will have access to the thread kernel port, but any thread may pass rights to its kernel port to any other thread.\
  3142. \fs20 \
  3143. \fs28 The function \b thread_reply()\b0  returns receive and send rights to the reply port of the calling thread.  The reply port is a port to which the thread has receive rights.  It\'27s used to receive any initialization messages and as a reply port for early remote procedure calls.\
  3144. \fs20 \
  3145. \fs28 A thread also has access to its task\'27s special ports.\
  3146. \fs20 \
  3147. \fs28 \pard \s24 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f0 \b \fs20 \fs10 \
  3148. \fs20     MACRO    \
  3149. \s17 \f1 \b0 \fs28 \f0 \b \fs20     EQUIVALENTS    \b0 \fs28 \f1 The following macros are defined in the header file \b mach/thread_special_ports.h\b0 :\
  3150. \fs20 \
  3151. \fs28 \pard \s44 \li2494 \fi0 \ri1007 \ql \tx6148 \tx10180 \b thread_get_reply_port(\b0 \i thread\i0 , \i port\b \i0 )\
  3152. \fi0 thread_set_reply_port(\b0 \i thread\i0 , \i port\b \i0 )\
  3153. \fs20 \
  3154. \fs28 \fi0 \b0 \b thread_get_exception_port(\b0 \i thread\i0 , \i port\b \i0 )\b0  \
  3155. \fi0 \b thread_set_exception_port(\b0 \i thread\i0 , \i port\b \i0 )\
  3156. \fs20 \
  3157. \fs28 \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs10 \
  3158. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The port was returned or set.\
  3159. \fs20 \
  3160. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i thread\i0  isn\'27t a thread, or \i which_port\i0  is an invalid port selector.\
  3161. \fs20 \
  3162. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3163. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b task_get_special_port()\b0 ,\b  task_set_special_port()\b0 ,\b  task_self()\b0 , \b thread_create()\
  3164. \fs20 \
  3165. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  3166. \fs28 thread_get_state()\b0 , \b thread_set_state()\
  3167. \fs20 \
  3168. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  3169. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get or set a thread\'27s state\
  3170. \fs28 \
  3171. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  3172. \fs10 \
  3173. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b thread_get_state(\b0 thread_t \i target_thread\i0 , int \i flavor\i0 , thread_state_data_t \i old_state\i0 , unsigned int *\i old_state_count\b \i0 )\
  3174. \b0 kern_return_t \b thread_set_state(\b0 thread_t \i target_thread\i0 , int \i flavor\i0 , thread_state_data_t \i new_state\i0 , unsigned int \i new_state_count\b \i0 )\
  3175. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  3176. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i target_thread\i0 :  The thread whose state is affected.\
  3177. \fs20 \
  3178. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i flavor\i0 :  The type of state that\'27s to be manipulated.  This may be any one of the following:\
  3179. \fs20 \
  3180. \fs28 \pard \s44 \li2494 \fi0 \ri1007 \ql \tx6148 \tx10180 NeXT_THREAD_STATE_REGS\
  3181. \fi0 NeXT_THREAD_STATE_68882 \
  3182. \fi0 NeXT_THREAD_STATE_USER_REG\
  3183. \fs20 \
  3184. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i old_state\i0 :  Returns an array of state information.\
  3185. \fs20 \
  3186. \fs28 \i new_state\i0 :  An array of state information.\
  3187. \fs20 \
  3188. \fs28 \i old_state_count\i0 :  The size of the state information array.  This may be any one of the following:\
  3189. \fs20 \
  3190. \fs28 \pard \s44 \li2494 \fi0 \ri1007 \ql \tx6148 \tx10180 NeXT_THREAD_STATE_REGS_COUNT \
  3191. \fi0 NeXT_THREAD_STATE_68882_COUNT\
  3192. \fi0 NeXT_THREAD_STATE_USER_REG_COUNT\
  3193. \fs20 \
  3194. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i new_state_count\i0 :  Same as \i old_state_count\i0 .\
  3195. \fs20 \
  3196. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3197. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b thread_get_state()\b0  returns the state component (that is, the machine registers) of \i target_thread\i0  as specified by \i flavor.  \i0 The \i old_state\i0  is an array of integers that\'27s provided by the caller and returned filled with the specified information.  You should set \i old_state_count\i0  to the maximum number of integers in \i old_state\i0 .  On return, \i old_state_count\i0  is equal to the actual number of integers in \i old_state\i0 .\
  3198. \fs20 \
  3199. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The function \b thread_set_state()\b0  sets the state component of \i target_thread\i0  as specified by \i flavor.  \i0 The \i new_state\i0  is an array of integers that the caller fills.  You should set \i new_state_count\i0  to the number of elements in \i new_state.  \i0 The entire set of registers is reset.\
  3200. \fs20 \
  3201. \fs28 \i target_thread\i0  must not be \b thread_self()\b0  for either of these calls.\
  3202. \fs20 \
  3203. \fs28 The state structures are defined in the header file \b mach/machine/thread_status.h\b0 .\
  3204. \fs20 \
  3205. \fs28 \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3206. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The state has been set or returned.\
  3207. \fs20 \
  3208. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 MIG_ARRAY_TOO_LARGE:  The returned state is too large for the \i new_state. \i0  The\i  new_state\i0  argument is filled in as much as possible, and \i new_state_count\i0  is set to the number of elements that would be returned if there were enough room.\
  3209. \fs20 \
  3210. \fs28 KERN_INVALID_ARGUMENT:  \i target_thread\i0  isn\'27t a thread, \i target_thread\i0  is \b thread_self()\b0 , or \i flavor\i0  is unrecognized for this machine.\
  3211. \fs20 \
  3212. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3213. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b task_info()\b0 , \b thread_info()\
  3214. \fs20 \
  3215. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  3216. \fs28 thread_info()\
  3217. \fs20 \
  3218. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  3219. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get information about a thread\
  3220. \fs28 \
  3221. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  3222. \fs10 \
  3223. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b thread_info(\b0 thread_t \i target_thread\i0 , int \i flavor\i0 , thread_info_t \i thread_info\i0 , unsigned int *\i thread_info_count\b \i0 )\
  3224. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  3225. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i target_thread\i0 :  The thread to be affected.\
  3226. \fs20 \
  3227. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i flavor\i0 :  The type of statistics wanted.  This can be THREAD_BASIC_INFO or THREAD_SCHED_INFO.\
  3228. \fs20 \
  3229. \fs28 \i thread_info\i0 :  Returns statistics about \i target_thread\i0 .\
  3230. \fs20 \
  3231. \fs28 \i thread_info_count\i0 :  Size of the info structure.  This can be THREAD_BASIC_INFO_COUNT or THREAD_SCHED_INFO_COUNT.\
  3232. \fs20 \
  3233. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3234. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b thread_info()\b0  returns the selected information array for a thread, as specified by \i flavor.  \i0 The \i thread_info\i0  argument is an array of integers that\'27s supplied by the caller and returned filled with specified information.  The \i thread_info_count\i0  argument is supplied as the maximum number of integers in \i thread_info.  \i0 On return, it contains the actual number of integers in \i thread_info\i0 .  \
  3235. \fs20 \
  3236. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The size of the information returned by THREAD_BASIC_INFO is defined by THREAD_BASIC_INFO_COUNT.  The definition of the information structure returned by THREAD_BASIC_INFO is:\
  3237. \fs20 \
  3238. \fs28 \pard \s12 \li2494 \fi0 \ri1007 \ql \f2 \fs24 struct thread_basic_info \{\
  3239. \fi0     time_value_t  user_time;     /* user run time */\
  3240. \fi0     time_value_t  system_time;   /* system run time */\
  3241. \fi0     int           cpu_usage;     /* scaled cpu usage percentage */\
  3242. \fi0     int           base_priority; /* base scheduling priority */\
  3243. \fi0     int           cur_priority;  /* current scheduling priority */\
  3244. \fi0     int           run_state;     /* run state */\
  3245. \fi0     int           flags;         /* various flags */\
  3246. \fi0     int           suspend_count; /* suspend count for thread */\
  3247. \fi0     long          sleep_time;    /* number of seconds that thread \
  3248. \fi0                                     has been sleeping */\
  3249. \fi0 \};\
  3250. \fi0 typedef struct thread_basic_info *thread_basic_info_t;\
  3251. \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \f1 \fs28 \fs20 \
  3252. \fs28 The \b run_state\b0  field has one of the following values:  \
  3253. \fs20 \
  3254. \fs28 \pard \s44 \li2494 \fi0 \ri1007 \ql \tx6148 \tx10180 TH_STATE_RUNNING:  The thread is running normally.\
  3255. \fs20 \
  3256. \fs28 TH_STATE_STOPPED:  The thread is suspended.  This happens when the thread or task suspend count is greater than zero.  \
  3257. \fs20 \
  3258. \fs28 TH_STATE_WAITING:  The thread is sleeping normally.\
  3259. \fs20 \
  3260. \fs28 TH_STATE_UNINTERRUPTIBLE:  The thread is in an uninterruptible sleep.  This should happen only for very short times during some\i  \i0 system calls.  \
  3261. \fs20 \
  3262. \fs28 TH_STATE_HALTED:  The thread is halted at a clean point.  This state happens only after a call to \b thread_abort()\b0 .  \
  3263. \fs20 \
  3264. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Possible values of the \b flags\b0  field are:\
  3265. \fs20 \
  3266. \fs28 \pard \s44 \li2494 \fi0 \ri1007 \ql \tx6148 \tx10180 TH_FLAGS_SWAPPED:  The thread is swapped out.  This happens when the thread hasn\'27t run in a long time, and the kernel stack for the thread has been swapped out.  \
  3267. \fs20 \
  3268. \fs28 TH_FLAGS_IDLE:  The thread is the idle thread for the CPU.  This means that the CPU runs this thread whenever it has no other threads to run.  \
  3269. \fs20 \
  3270. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The \b sleep_time\b0  field is useful only when \b run_state\b0  is TH_STATE_STOPPED.  (Currently \b sleep_time\b0  is always set to zero, no matter how long the thread has been sleeping.)\
  3271. \fs20 \
  3272. \fs28 The size of the information returned by THREAD_SCHED_INFO is defined by THREAD_SCHED_INFO_COUNT.  The definition of the information structure returned by THREAD_SCHED_INFO is:\
  3273. \fs20 \
  3274. \fs28 \pard \s12 \li2494 \fi0 \ri1007 \ql \f2 \fs24 struct thread_sched_info \{\
  3275. \fi0     int       policy;           /* scheduling policy */\
  3276. \fi0     int       data;             /* associated data */\
  3277. \fi0     int       base_priority;    /* base priority */\
  3278. \fi0     int       max_priority;     /* max priority */\
  3279. \fi0     int       cur_priority;     /* current priority */\
  3280. \fi0     boolean_t depressed;        /* depressed ? */\
  3281. \fi0     int       depress_priority; /* priority depressed from */\
  3282. \fi0 \};\
  3283. \fi0 typedef struct thread_sched_info    *thread_sched_info_t;\
  3284. \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \f1 \fs28 \fs20 \
  3285. \fs28 The \b policy\b0  field has one of the following values:  POLICY_FIXEDPRI, POLICY_TIMESHARE, or POLICY_INTERACTIVE.  If \b policy\b0  is POLICY_FIXEDPRI, then \b data\b0  is the quantum (in milliseconds).  Otherwise, \b data\b0  is meaningless.\
  3286. \fs20 \
  3287. \fs28 \pard \s19 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3288. \fs28 \f0 \b \fs20     EXAMPLE    \b0 \fs28 \f1 Example of using THREAD_BASIC_INFO:\
  3289. \fs20 \
  3290. \fs28 \pard \s12 \li2494 \fi0 \ri1007 \ql \f2 \fs24 kern_return_t             error;\
  3291. \fi0 struct thread_basic_info  info;\
  3292. \fi0 unsigned int              info_count=THREAD_BASIC_INFO_COUNT;\
  3293. \fi0 \
  3294. \fi0 error=thread_info(thread_self(), THREAD_BASIC_INFO, \
  3295. \fi0     (thread_info_t)&info, &info_count);\
  3296. \fi0 if (error!=KERN_SUCCESS)\
  3297. \fi0     mach_error("Error calling thread_info()", error);\
  3298. \fi0 else \{\
  3299. \fi0     printf("User time is %d seconds, %d microseconds\\n", \
  3300. \fi0         info.user_time.seconds, info.user_time.microseconds);\
  3301. \fi0     printf("System time is %d seconds, %d microseconds\\n", \
  3302. \fi0         info.system_time.seconds, info.system_time.microseconds);\
  3303. \fi0 \}\
  3304. \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \f1 \fs28 \fs20 \
  3305. \fs28 Example of using THREAD_SCHED_INFO:\
  3306. \fs20 \
  3307. \fs28 \s12 \li2494 \fi-378 \fi0 \f2 \fs24 kern_return_t             error;\
  3308. \fi0 struct thread_sched_info  info;\
  3309. \fi0 unsigned int              info_count=THREAD_SCHED_INFO_COUNT;\
  3310. \fi0 \
  3311. error=thread_info(thread_self(), THREAD_SCHED_INFO, \
  3312. \fi0     (thread_info_t)&info, &info_count);\
  3313. \fi0 if (error!=KERN_SUCCESS)\
  3314. \fi0     mach_error("Error calling thread_info()", error);\
  3315. \fi0 else \{\
  3316. \fi0     printf("Base priority is %d\\n", info.base_priority);\
  3317. \fi0     printf("Max priority is %d\\n", info.max_priority);\
  3318. \fi0 \}\
  3319. \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  3320. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  3321. \fs20 \
  3322. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i target_thread\i0  isn\'27t a thread, or \i flavor\i0  isn\'27t recognized, or\i  thread_info_count \i0 is smaller than it\'27s supposed to be.\
  3323. \fs20 \
  3324. \fs28 MIG_ARRAY_TOO_LARGE:  The returned info array is too large for \i thread_info.  \i0 The\i  thread_info\i0  argument is filled as much as possible, and \i thread_info_count\i0  is set to the number of elements that would have been returned if there were enough room.\
  3325. \fs20 \
  3326. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3327. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b thread_get_special_port()\b0 , \b task_threads()\b0 , \b task_info()\b0 , \b thread_get_state()\
  3328. \fs20 \
  3329. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  3330. \fs28 thread_policy()\
  3331. \fs20 \
  3332. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  3333. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Set scheduling policy for a thread\
  3334. \fs28 \
  3335. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  3336. \fs10 \
  3337. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b thread_policy(\b0 thread_t \i thread\i0 , int \i policy\i0 , int \i data\b \i0 )\
  3338. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  3339. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i thread\i0 :  Thread to set policy for.\
  3340. \fs20 \
  3341. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i policy\i0 :  Policy to set.  This must be POLICY_TIMESHARE, POLICY_INTERACTIVE, or POLICY_FIXEDPRI.\
  3342. \fs20 \
  3343. \fs28 \i data\i0 :  Policy-specific data.\
  3344. \fs20 \
  3345. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3346. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 This function changes the scheduling policy for \i thread\i0  to \i policy\i0 .  \
  3347. \fs20 \
  3348. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The \i data\i0  argument is meaningless for the timesharing and interactive policies; for the fixed-priority policy, it\'27s the quantum to be used (in milliseconds).  The system will always round the quantum up to the next multiple of the basic system quantum (\b min_quantum\b0 , which can be obtained from \b host_info()\b0 ).  You can find the current quantum using \b thread_info()\b0 .  \
  3349. \fs20 \
  3350. \fs28 Processor sets can restrict the allowed policies, so this call will fail if the processor set to which \i thread\i0  is currently assigned doesn\'27t permit \i policy\i0 .\
  3351. \fs20 \
  3352. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  3353. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 kern_return_t           error;\
  3354. \fi0 struct host_sched_info  sched_info;\
  3355. \fi0 unsigned int            sched_count=HOST_SCHED_INFO_COUNT;\
  3356. \fi0 int                     quantum;\
  3357. \fi0 processor_set_t         default_set, default_set_priv;\
  3358. \fi0 \
  3359. \fi0 /* Set quantum to a reasonable value. */\
  3360. \fi0 error=host_info(host_self(), HOST_SCHED_INFO, \
  3361. \fi0     (host_info_t)&sched_info, &sched_count);\
  3362. \fi0 if (error != KERN_SUCCESS) \{\
  3363. \fi0     mach_error("SCHED host_info() call failed", error);\
  3364. \fi0     exit(1);\
  3365. \fi0 \}\
  3366. \fi0 else\
  3367. \fi0     quantum = sched_info.min_quantum;\
  3368. \pard \s14 \li2116 \fi0 \ri503 \ql \
  3369. /*\
  3370. \fi0  * Fix the default processor set to take a fixed priority thread.\
  3371. \fi0  */\
  3372. \fi0 error=processor_set_default(host_self(), &default_set);\
  3373. \fi0 if (error!=KERN_SUCCESS) \{\
  3374. \fi0     mach_error("Error calling processor_set_default()", error);\
  3375. \fi0     exit(1);\
  3376. \fi0 \}\
  3377. \fi0 \
  3378. error=host_processor_set_priv(host_priv_self(), default_set,\
  3379. \fi0     &default_set_priv);\
  3380. \fi0 if (error != KERN_SUCCESS) \{\
  3381. \fi0     mach_error("Call to host_processor_set_priv() failed", error);\
  3382. \fi0     exit(1);\
  3383. \fi0 \}\
  3384. \fi0 \
  3385. \fi0 error=processor_set_policy_enable(default_set_priv, POLICY_FIXEDPRI);\
  3386. \fi0 if (error != KERN_SUCCESS)\
  3387. \fi0     mach_error("Error calling processor_set_policy_enable", error);\
  3388. \fi0 \
  3389. /*\
  3390. \fi0  * Change the thread\'27s scheduling policy to fixed priority.\
  3391. \fi0  */\
  3392. \fi0 error=thread_policy(thread_self(), POLICY_FIXEDPRI, quantum);\
  3393. \fi0 if (error != KERN_SUCCESS)\
  3394. \fi0     mach_error("thread_policy() call failed", error);\
  3395. \fi0 \
  3396. \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  3397. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  3398. \fs20 \
  3399. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i thread\i0  is not a thread, or \i policy\i0  is not a recognized policy.\
  3400. \fs20 \
  3401. \fs28 KERN_FAILURE:  The processor set to which \i thread\i0  is currently assigned doesn\'27t permit \i policy\i0 .\
  3402. \fs20 \
  3403. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3404. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b processor_set_policy()\b0 , \b thread_switch()\
  3405. \fs20 \
  3406. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  3407. \fs28 thread_priority(), thread_max_priority()\
  3408. \fs20 \
  3409. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  3410. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Set scheduling priority for thread\
  3411. \fs28 \
  3412. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  3413. \fs10 \
  3414. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b thread_priority(\b0 thread_t \i thread\i0 , int \i priority\i0 , boolean_t \i set_max\b \i0 )\
  3415. \b0 kern_return_t \b thread_max_priority(\b0 thread_t \i thread\i0 , processor_set_t \i processor_set\i0 , int \i priority\b \i0 )\
  3416. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  3417. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i thread\i0 :  The thread whose priority is to be changed.\
  3418. \fs20 \
  3419. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i priority\i0 :  The new priority to change it to.\
  3420. \fs20 \
  3421. \fs28 \i set_max\i0 :  Also set \i thread\i0 \'27s maximum priority if true.\
  3422. \fs20 \
  3423. \fs28 \i processor_set\i0 :  The privileged port for the processor set to which \i thread\i0  is currently assigned.\
  3424. \fs20 \
  3425. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3426. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 Threads have three priorities associated with them by the system:  a \i base priority\i0 , a \i maximum priority\i0 , and a \i scheduled priority\i0 .  \
  3427. \fs20 \
  3428. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The scheduled priority is used to make scheduling decisions about the thread.  It\'27s determined from the base priority by the policy.  (For the timesharing and interactive policies, this means adding an increment derived from CPU usage).  The base priority can be set under user control, but can never exceed the maximum priority.  Raising the maximum priority requires presentation of the privileged port for the thread\'27s processor set; since the privileged port for the default processor set is available only to the superuser, users cannot raise their maximum priority to unfairly compete with other users on that set.  Newly created threads obtain their base priority from the task and their maximum priority from the thread.  \
  3429. \fs20 \
  3430. \fs28 Priorities range from 0 to 31, where higher numbers denote higher priorities.  You can obtain the base, scheduled, and maximum priorities using \b thread_info()\b0 .\
  3431. \fs20 \
  3432. \fs28 The \b thread_priority()\b0  function changes the base priority and optionally the maximum priority of \i thread\i0 .  If the new base priority is higher than the\i  \i0 scheduled\i  \i0 priority of the currently executing thread, preemption may occur as a result of this call.  The maximum priority of the thread is also set if \i set_max\i0  is true.  This call fails if \i priority\i0  is greater than the current maximum priority of the thread.  As a result, \b thread_priority()\b0  can lower\'d0but never raise\'d0the value of a thread\'27s maximum priority.\
  3433. \fs20 \
  3434. \fs28 The \b thread_max_priority()\b0  function changes the maximum priority of the thread.  Because it requires the privileged port for the processor set, this call can reset the maximum priority to any legal value.  If the new maximum priority is less than the thread\'27s base priority, then the thread\'27s base priority is set to the new maximum priority.\
  3435. \fs20 \
  3436. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  3437. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 /* Get the privileged port for the default processor set. */\
  3438. \fi0 error=processor_set_default(host_self(), &default_set);\
  3439. \fi0 if (error!=KERN_SUCCESS) \{\
  3440. \fi0     mach_error("Error calling processor_set_default()", error);\
  3441. \fi0     exit(1);\
  3442. \fi0 \}\
  3443. \pard \s14 \li2116 \fi0 \ri503 \ql \
  3444. error=host_processor_set_priv(host_priv_self(), default_set,\
  3445. \fi0     &default_set_priv);\
  3446. \fi0 if (error!=KERN_SUCCESS) \{\
  3447. \fi0     mach_error("Call to host_processor_set_priv() failed", error);\
  3448. \fi0     exit(1);\
  3449. \fi0 \}\
  3450. \fi0 \
  3451. /* Set the max priority. */\
  3452. \fi0 error=thread_max_priority(thread_self(), default_set_priv, priority);\
  3453. \fi0 if (error!=KERN_SUCCESS)\
  3454. \fi0     mach_error("Call to thread_max_priority() failed",error);\
  3455. \fi0 \
  3456. /* Set the thread\'27s priority. */\
  3457. \fi0 error=thread_priority(thread_self(), priority, FALSE);\
  3458. \fi0 if (error!=KERN_SUCCESS)\
  3459. \fi0     mach_error("Call to thread_priority() failed",error);\
  3460. \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  3461. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  Operation completed successfully.\
  3462. \fs20 \
  3463. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i thread\i0  is not a thread, \i processor_set\i0  is not a privileged port for a processor set, or \i priority\i0  is out of range (not in 0-31).\
  3464. \fs20 \
  3465. \fs28 KERN_FAILURE:  The requested operation would violate the thread\'27s maximum (only for \b thread_priority()\b0 ), or the thread is not assigned to the processor set whose privileged port was presented.\
  3466. \fs20 \
  3467. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3468. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b thread_policy()\b0 , \b task_priority()\b0 , \b processor_set_priority()\b0 , \b thread_switch()\
  3469. \fs20 \
  3470. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  3471. \fs28 thread_resume()\
  3472. \fs20 \
  3473. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  3474. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Resume a thread\
  3475. \fs28 \
  3476. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  3477. \fs10 \
  3478. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b thread_resume(\b0 thread_t \i target_thread\b \i0 )\
  3479. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  3480. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i target_thread\i0 :  The thread to be resumed.\
  3481. \fs20 \
  3482. \fs28 \s16 \fs10 \
  3483. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b thread_resume()\b0  decrements the thread\'27s suspend count.  If the count becomes 0, the thread is resumed.  If it\'27s still positive, the thread is left suspended.  The suspend count never becomes negative.\
  3484. \fs20 \
  3485. \fs28 \s25 \fs10 \
  3486. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The thread has been resumed.\
  3487. \fs20 \
  3488. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_FAILURE:  The suspend count is already 0.\
  3489. \fs20 \
  3490. \fs28 KERN_INVALID_ARGUMENT:  \i target_thread\i0  isn\'27t a thread.\
  3491. \fs20 \
  3492. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3493. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b task_suspend()\b0 , \b task_resume()\b0 , \b thread_info()\b0 , \b thread_create()\b0 , \b thread_terminate()\b0 , \b thread_suspend()\
  3494. \fs20 \
  3495. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  3496. \fs28 thread_suspend()\
  3497. \fs20 \
  3498. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  3499. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Suspend a thread\
  3500. \fs28 \
  3501. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  3502. \fs10 \
  3503. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b thread_suspend(\b0 thread_t \i target_thread\b \i0 )\
  3504. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  3505. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i target_thread\i0 :  The thread to be suspended.\
  3506. \fs20 \
  3507. \fs28 \s16 \fs10 \
  3508. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b thread_suspend()\b0  increments the thread\'27s suspend count and prevents the thread from executing any more user-level instructions.  In this context, a user-level instruction is either a machine instruction executed in user mode or a system trap instruction (including page faults).\
  3509. \fs20 \
  3510. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 If a thread is currently executing within a system trap, the kernel code may continue to execute until it reaches the system return code, or it may suspend within the kernel code.  In either case, when the thread is resumed the system trap will return.  This could cause unpredictable results if you did a suspend and then altered the user state of the thread in order to change its direction upon a resume.  The function \b thread_abort()\b0  lets you abort any currently executing system call in a predictable way.\
  3511. \fs20 \
  3512. \fs28 If the suspend count becomes greater than 1, it will take more than one \b thread_resume()\b0  call to restart the thread.\
  3513. \fs20 \
  3514. \fs28 \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3515. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The thread has been suspended.\
  3516. \fs20 \
  3517. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i target_thread\i0  isn\'27t a thread.\
  3518. \fs20 \
  3519. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3520. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b task_suspend()\b0 , \b task_resume()\b0 , \b thread_get_state()\b0 , \b thread_info()\b0 , \b thread_resume()\b0 , \b thread_terminate()\b0 , \b thread_abort()\
  3521. \fs20 \
  3522. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  3523. \fs28 thread_switch()\
  3524. \fs20 \
  3525. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  3526. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Cause a context switch\
  3527. \fs28 \
  3528. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  3529. \fs10 \
  3530. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b thread_switch(\b0 thread_t \i new_thread\i0 , int \i option\i0 , int \i time\b \i0 )\
  3531. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  3532. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i new_thread\i0 :  Thread to switch to.  If you specify THREAD_NULL, be sure to specify the \i option\i0  argument to be either SWITCH_OPTION_WAIT or SWITCH_OPTION_DEPRESS.\
  3533. \fs20 \
  3534. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i option\i0 :  Specifies options associated with context switch.  Three options are recognized:\
  3535. \fs20 \
  3536. \fs28 \pard \s5 \li2494 \fi0 \ri1007 \ql \tx2872 \tx3250 \tx3642 SWITCH_OPTION_NONE:  No options; the \i time\i0  argument is ignored.  (You must set \i new_thread\i0  to a valid thread.)\
  3537. \fs20 \
  3538. \fs28 SWITCH_OPTION_WAIT:  This thread is blocked for the specified time.  The block can be aborted by \b thread_abort()\b0 .\
  3539. \fs20 \
  3540. \fs28 SWITCH_OPTION_DEPRESS:  This thread\'27s priority is depressed to the lowest possible value until one of the following happens:  \i time\i0  milliseconds pass, this thread is scheduled again, or \b thread_abort()\b0  is called on this thread (whichever happens first).  Priority depression is independent of operations that change this thread\'27s priority; for example, \b thread_priority()\b0  will not abort the depression.\
  3541. \fs20 \
  3542. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i time\i0 :  Time duration (in milliseconds\i ) \i0 for options.  The minimum time can be obtained as the \b min_timeout\b0  value from \b host_info()\b0 .\
  3543. \fs20 \
  3544. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3545. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 This function provides low-level access to the scheduler\'27s context switching code.  \i new_thread\i0  is a hint that implements handoff scheduling.  The operating system will attempt to switch directly to \i new_thread\i0  (bypassing the normal logic that selects the next thread to run) if possible.  If \i new_thread\i0  isn\'27t valid or THREAD_NULL, \b thread_switch()\b0  returns an error.\
  3546. \fs20 \
  3547. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The \b thread_switch()\b0  function is often called when the current thread can proceed no farther for some reason; the various options and arguments allow information about this reason to be transmitted to the kernel.  The \i new_thread\i0  argument (handoff scheduling) is useful when the identity of the thread that must make progress before the current thread runs again is known.  The SWITCH_OPTION_WAIT option is used when the amount of time that the current thread must wait before it can do anything useful can be estimated and is fairly long.  The SWITCH_OPTION_DEPRESS option is used when the required waiting time is fairly short, especially when the identity of the thread that is being waited for is not known.\
  3548. \fs20 \
  3549. \fs28 Users should beware of calling \b thread_switch()\b0  with an invalid \i new_thread\i0  (for example, THREAD_NULL) and no \i option\i0 .  Because the timesharing and interactive schedulers vary the priority of threads based on usage, this may result in a waste of CPU time if the thread that must be run is of lower priority.  The use of the SWITCH_OPTION_DEPRESS option in this situation is highly recommended.\
  3550. \fs20 \
  3551. \fs28 When a thread that\'27s depressed is scheduled, it regains its old priority.  The code should recheck the conditions to see if it wants to depress again.  If \b thread_abort()\b0  is called on a depressed thread, the priority of the thread is restored.\
  3552. \fs20 \
  3553. \fs28 Users relying on the preemption semantics of a fixed-priority policy should be aware that \b thread_switch()\b0  ignores these semantics; it will run the specified \i new_thread\i0  independent of its priority and the priority of any other threads that could be run instead.\
  3554. \fs20 \
  3555. \fs28 \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3556. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.  \
  3557. \fs20 \
  3558. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i new_thread\b \i0  \b0 is not a thread, or \i option\i0  is not a recognized option.\
  3559. \fs20 \
  3560. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 \fs60 \
  3561. \fs28 thread_terminate()\
  3562. \fs20 \
  3563. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  3564. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Terminate a thread\
  3565. \fs28 \
  3566. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  3567. \fs10 \
  3568. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b thread_terminate(\b0 thread_t \i target_thread\b \i0 )\
  3569. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  3570. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i target_thread\i0 :  The thread to be destroyed.\
  3571. \fs20 \
  3572. \fs28 \s16 \fs10 \
  3573. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b thread_terminate()\b0  destroys the thread specified by \i target_thread\i0 .\
  3574. \fs20 \
  3575. \fs28 \pard \s48 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Warning:  \b0 \fs28 \f1 Don\'27t use this function on threads that were created using the C-thread functions.  Each C thread must terminate itself either explicitly, by calling \b cthread_exit()\b0 , or implicitly, by returning from its top-level function.\
  3576. \fs20 \
  3577. \fs28 \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3578. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The thread has been destroyed.\
  3579. \fs20 \
  3580. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  \i target_thread\i0  isn\'27t a thread.\
  3581. \fs20 \
  3582. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3583. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b task_terminate()\b0 , \b task_threads()\b0 , \b thread_create()\b0 , \b thread_resume()\b0 , \b thread_suspend()\
  3584. \fs20 \
  3585. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  3586. \fs28 unix_pid() \
  3587. \fs20 \
  3588. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  3589. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get the process ID of a task\
  3590. \fs28 \
  3591. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  3592. \fs10 \
  3593. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b unix_pid(\b0 task_t \i target_task\i0 , int *\i pid\b \i0 )\
  3594. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  3595. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i target_task\i0 :  The task for which you want the process ID.\
  3596. \fs20 \
  3597. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i pid\i0 :  Returns the process ID of \i target_task\i0 .\
  3598. \fs20 \
  3599. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3600. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 Returns the process ID of \i target_task\i0 .  If the call doesn\'27t succeed, \i pid\i0  is set to -1.\
  3601. \fs20 \
  3602. \fs28 \s18 \f2 \fs24 \fs10 \
  3603. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 result=unix_pid(task_self(), &my_pid);\
  3604. \fi0 if (result!=KERN_SUCCESS) \{\
  3605. \fi0     mach_error("Call to unix_pid failed", result);\
  3606. \fi0     exit(1);\
  3607. \fi0 \}\
  3608. \fi0 \
  3609. \fi0 printf("My process ID is %d\\n", my_pid);\
  3610. \s25 \fi-2015 \f1 \fs28 \fs28 \
  3611. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The call succeeded.\
  3612. \fs20 \
  3613. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_FAILURE:  \i target_task\i0  isn\'27t a valid task.  This might be because \i target_task\i0  is a pure Mach task (one created using \b task_create()\b0 ).\
  3614. \fs20 \
  3615. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b \fs10 \
  3616. \fs28 \f0 \fs20     SEE ALSO    \fs28 \f1 task_by_unix_pid()\
  3617. \fs20 \
  3618. \fs28 \s20 \fi0 \f0 \fs28 \fs60 \
  3619. \fs28 vm_allocate()\
  3620. \fs20 \
  3621. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  3622. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Allocate virtual memory\
  3623. \fs28 \
  3624. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  3625. \fs10 \
  3626. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b vm_allocate(\b0 vm_task_t \i target_task\i0 , vm_address_t *\i address\i0 , vm_size_t \i size\i0 , boolean_t \i anywhere\b \i0 )\
  3627. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  3628. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i target_task\i0 :  Task whose virtual memory is to be affected.  Use \b task_self()\b0  to allocate memory in the caller\'27s address space.\
  3629. \fs20 \
  3630. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i address\i0 :  Starting address.  If \i anywhere\i0  is true, the input value of this address will be ignored, and the space will be allocated wherever it\'27s available.  If \i anywhere\i0  is false, an attempt is made to allocate virtual memory starting at this virtual address.  If this address isn\'27t at the beginning of a virtual page, it gets rounded down so that it is.  If there isn\'27t enough space at this address, no memory will be allocated.  No matter what the value of \i anywhere\i0  is, the address at which memory is actually allocated is returned in \i address\i0 .\
  3631. \fs20 \
  3632. \fs28 \i size\i0 :  Number of bytes to allocate (rounded up by the system to an integral number of virtual pages).\
  3633. \fs20 \
  3634. \fs28 \i anywhere\i0 :  If true, the kernel should find and allocate any region of the specified size.  If false, virtual memory is allocated starting at \i address\i0  (rounded down to a virtual page boundary) if sufficient space exists.\
  3635. \fs20 \
  3636. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3637. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b vm_allocate()\b0  allocates a region of virtual memory, placing it in the address space of the specified task.  The physical memory isn\'27t actually allocated until the new virtual memory is referenced.  By default, the kernel rounds all addresses down to the nearest page boundary and all memory sizes up to the nearest page size.  The global variable \b vm_page_size\b0  contains the page size.  For languages other than C, the value of \b vm_page_size\b0  can be obtained by calling \b vm_statistics()\b0 .\
  3638. \fs20 \
  3639. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Initially, the pages of allocated memory are protected to allow all forms of access, and are inherited in child tasks as a copy.  Subsequent calls to \b vm_protect()\b0  and \b vm_inherit()\b0  may be used to change these properties.  The allocated region is always zero-filled.\
  3640. \fs20 \
  3641. \fs28 \pard \s37 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Note:  \b0 \fs28 \f1 Unless you have a special reason for calling \b vm_allocate()\b0  (such as a need for page-aligned memory), you should usually call \b malloc()\b0  or a similar C library function instead.  The C library functions don\'27t necessarily make UNIX or Mach system calls, so they\'27re generally faster than using a Mach function such as \b vm_allocate()\b0 .  \
  3642. \fs20 \
  3643. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  3644. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 if ((ret = vm_allocate(task_self(), (vm_address_t *)&lock,\
  3645. \fi0     sizeof(int), TRUE)) != KERN_SUCCESS) \{ \
  3646. \fi0     mach_error("vm_allocate returned value of ", ret); \
  3647. \fi0     printf("Exiting with error.\\n"); \
  3648. \fi0     exit(-1); \
  3649. \fi0 \} \
  3650. \fi0 if ((ret = vm_inherit(task_self(), (vm_address_t)lock, sizeof(int), \
  3651. \fi0         VM_INHERIT_SHARE)) != KERN_SUCCESS) \{ \
  3652. \fi0     mach_error("vm_inherit returned value of ", ret); \
  3653. \fi0     printf("Exiting with error.\\n"); \
  3654. \fi0     exit(-1); \
  3655. \fi0 \} \
  3656. \s25 \fi-2015 \f1 \fs28 \fs28 \
  3657. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  Memory allocated.\
  3658. \fs20 \
  3659. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ADDRESS:  Illegal address specified.\
  3660. \fs20 \
  3661. \fs28 KERN_NO_SPACE:  Not enough space left to satisfy this request.\
  3662. \fs20 \
  3663. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3664. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b vm_deallocate()\b0 , \b vm_inherit()\b0 , \b vm_protect()\b0 , \b vm_region()\b0 , \b vm_statistics()\
  3665. \fs20 \
  3666. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  3667. \fs28 vm_copy()\
  3668. \fs20 \
  3669. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  3670. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Copy virtual memory\
  3671. \fs28 \
  3672. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  3673. \fs10 \
  3674. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b vm_copy(\b0 vm_task_t \i target_task\i0 , vm_address_t \i source_address\i0 , vm_size_t \i size\i0 , vm_address_t \i dest_address\b \i0 )\
  3675. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  3676. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i target_task\i0 :  The task whose virtual memory is to be affected.\
  3677. \fs20 \
  3678. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i source_address\i0 :  The address in \i target_task\i0  of the start of the source range (must be a page boundary).\
  3679. \fs20 \
  3680. \fs28 \i size\i0 :  The number of bytes to copy (must be a multiple of \b vm_page_size\b0 ).  \
  3681. \fs20 \
  3682. \fs28 \i dest_address\i0 :  The address in \i target_task\i0  of the start of the destination range (must be a page boundary).\
  3683. \fs20 \
  3684. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3685. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b vm_copy()\b0  causes the source memory range to be copied to the destination address; the destination region must not overlap the source region.  The destination address range must already be allocated and writable; the source range must be readable.  \
  3686. \fs20 \
  3687. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 For languages other than C, the value of \b vm_page_size\b0  can be obtained by calling \b vm_statistics()\b0 .\
  3688. \fs20 \
  3689. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  3690. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 if ((rtn = vm_allocate(task_self(), (vm_address_t *)&data1, \
  3691. \fi0         vm_page_size, TRUE)) != KERN_SUCCESS) \{ \
  3692. \fi0     mach_error("vm_allocate returned value of ", rtn); \
  3693. \fi0     printf("vm_copy: Exiting.\\n"); \
  3694. \fi0     exit(-1); \
  3695. \fi0 \}\
  3696. \pard \s14 \li2116 \fi0 \ri503 \ql \
  3697. temp = data1; \
  3698. \fi0 for (i = 0; (i < vm_page_size / sizeof(int)); i++) \
  3699. \fi0     temp[i] = i; \
  3700. \fi0 printf("vm_copy: set data\\n");\
  3701. \fi0 \
  3702. \fi0 if ((rtn = vm_allocate(task_self(), (vm_address_t *)&data2, \
  3703. \fi0         vm_page_size, TRUE)) != KERN_SUCCESS) \{ \
  3704. \fi0     mach_error("vm_allocate returned value of ", rtn); \
  3705. \fi0     printf("vm_copy: Exiting.\\n"); \
  3706. \fi0     exit(-1); \
  3707. \fi0 \}\
  3708. \fi0 \
  3709. if ((rtn = vm_copy(task_self(), (vm_address_t)data1, vm_page_size, \
  3710. \fi0         (vm_address_t)data2)) != KERN_SUCCESS) \{ \
  3711. \fi0     mach_error("vm_copy returned value of ", rtn); \
  3712. \fi0     printf("vm_copy: Exiting.\\n"); \
  3713. \fi0     exit(-1); \
  3714. \fi0 \} \
  3715. \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  3716. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  Memory copied.\
  3717. \fs20 \
  3718. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  The address doesn\'27t start on a page boundary or the size isn\'27t a multiple of \b vm_page_size\b0 .\
  3719. \fs20 \
  3720. \fs28 KERN_PROTECTION_FAILURE:  The destination region isn\'27t writable, or the source region isn\'27t readable.\
  3721. \fs20 \
  3722. \fs28 KERN_INVALID_ADDRESS:  An illegal or nonallocated address was specified, or insufficient memory was allocated at one of the addresses.\
  3723. \fs20 \
  3724. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3725. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b vm_allocate()\b0 , \b vm_protect()\b0 , \b vm_write()\b0 , \b vm_statistics()\
  3726. \fs20 \
  3727. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  3728. \fs28 vm_deactivate()\
  3729. \fs20 \
  3730. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  3731. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Mark virtual memory as unlikely to be used soon\
  3732. \fs28 \
  3733. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  3734. \fs10 \
  3735. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b vm_deactivate(\b0 vm_task_t \i target_task\i0 , vm_address_t \i address\i0 , vm_size_t \i size\i0 , int\i  when\b \i0 )\
  3736. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  3737. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i target_task\i0 :  Task whose virtual memory is to be affected.\
  3738. \fs20 \
  3739. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i address\i0 :  Starting address (must be on a page boundary).\
  3740. \fs20 \
  3741. \fs28 \i size\i0 :  The number of bytes to deactivate (must be a multiple of \b vm_page_size\b0 ).  Specifying 0 deactivates all of the task\'27s memory at or above \i address\i0 .\
  3742. \fs20 \
  3743. \fs28 \i when\i0 :  A mask specifying how aggressively the system should deactivate the memory, and whether the memory should be deactivated if it\'27s shared.  Values for \i when\i0  are defined in the header file \b mach/vm_policy.h\b0 .\
  3744. \fs20 \
  3745. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3746. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 This function lets you tell the operating system that a region of memory won\'27t be used for a long time. It differs from \b vm_deallocate()\b0  in that the task\'27s mapping to the memory is retained; only the physical memory associated with the region is affected.\
  3747. \fs20 \
  3748. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 A \i when\i0  value of VM_DEACTIVATE_NOW is the most extreme\'d0the system will immediately place clean pages at the front of the free list, and dirty pages at the front of the inactive list.  A \i when\i0  value of VM_DEACTIVATE_SOON specifies that the system should place all pages on the tail of the inactive list.  You can add the mask VM_DEACTIVATE_SHARED to indicate that only shared memory should be affected.\
  3749. \fs20 \
  3750. \fs28 This call is used in the window server to deactivate the backing stores of windows in hidden applications, and is used in the Application Kit to deactivate the text, data, and stack of hidden applications.\
  3751. \fs20 \
  3752. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3753. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b vm_set_policy()\
  3754. \fs20 \
  3755. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  3756. \fs28 vm_deallocate()\
  3757. \fs20 \
  3758. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  3759. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Deallocate virtual memory\
  3760. \fs28 \
  3761. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  3762. \fs10 \
  3763. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b vm_deallocate(\b0 vm_task_t \i target_task\i0 , vm_address_t \i address\i0 , vm_size_t \i size\b \i0 )\
  3764. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  3765. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i target_task\i0 :  Task whose virtual memory is to be affected.\
  3766. \fs20 \
  3767. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i address\i0 :  Starting address (this gets rounded down to a page boundary).\
  3768. \fs20 \
  3769. \fs28 \i size\i0 :  Number of bytes to deallocate (this gets rounded up to a page boundary).\
  3770. \fs20 \
  3771. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3772. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b vm_deallocate()\b0  relinquishes access to a region of a task\'27s address space, causing further access to that memory to fail.  This address range will be available for reallocation.  Note that because of the rounding to virtual page boundaries, more than \i size\i0  bytes may be deallocated.  Use \b vm_statistics()\b0  or the global variable \b vm_page_size\b0  to get the current virtual page size.\
  3773. \fs20 \
  3774. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 This function may be used to deallocate memory that was passed to a task in a message (using out-of-line data).  In that case, the rounding should cause no trouble, since the region of memory was allocated as a set of pages.\
  3775. \fs20 \
  3776. \fs28 The function \b vm_deallocate()\b0  affects only the task specified by \i target_task.  \i0 Other tasks that may have access to this memory can continue to reference it.\
  3777. \fs20 \
  3778. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  3779. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 r = vm_deallocate(task_self(), (vm_address_t)thread_list, \
  3780. \fi0     sizeof(thread_list)*thread_count);\
  3781. \fi0 if (r != KERN_SUCCESS)\
  3782. \fi0     mach_error("Trouble freeing thread_list", r);\
  3783. \s25 \fi-2015 \f1 \fs28 \fs28 \
  3784. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  Memory deallocated.\
  3785. \fs20 \
  3786. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ADDRESS:  Illegal or nonallocated address specified.\
  3787. \fs20 \
  3788. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3789. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b vm_allocate()\b0 , \b vm_statistics()\b0 , \b msg_receive()\
  3790. \fs20 \
  3791. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  3792. \fs28 vm_inherit()\
  3793. \fs20 \
  3794. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  3795. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Inherit virtual memory\
  3796. \fs28 \
  3797. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  3798. \fs10 \
  3799. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b vm_inherit(\b0 vm_task_t \i target_task\i0 , vm_address_t \i address\i0 , vm_size_t \i size\i0 , vm_inherit_t \i new_inheritance\b \i0 )\
  3800. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  3801. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i target_task\i0 :  Task whose virtual memory is to be affected.\
  3802. \fs20 \
  3803. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i address\i0 :  Starting address (this gets rounded down to a page boundary).\
  3804. \fs20 \
  3805. \fs28 \i size\i0 :  Size in bytes of the region for which inheritance is to change (this gets rounded up to a page boundary).\
  3806. \fs20 \
  3807. \fs28 \i new_inheritance\i0 :  How this memory is to be inherited in child tasks.  Inheritance is specified by using one of these following three values:\
  3808. \fs20 \
  3809. \fs28 \pard \s44 \li2494 \fi0 \ri1007 \ql \tx6148 \tx10180 VM_INHERIT_SHARE:  Child tasks will share this memory with this task.\
  3810. \fi0 VM_INHERIT_COPY:  Child tasks will receive a copy of this region.\
  3811. \fi0 VM_INHERIT_NONE:  This region will be absent from child tasks.\
  3812. \fs20 \
  3813. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3814. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b vm_inherit()\b0  specifies how a region of a task\'27s address space is to be passed to child tasks at the time of task creation.  Inheritance is an attribute of virtual pages; thus the addresses and size of memory to be set will be rounded to refer to whole pages.\
  3815. \fs20 \
  3816. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Setting \b vm_inherit()\b0  to VM_INHERIT_SHARE and forking a child task is the only way two Mach tasks can share physical memory.  However, all the threads of a given task share all the same memory.\
  3817. \fs20 \
  3818. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  3819. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 if ((ret = vm_allocate(task_self(), (vm_address_t *)&lock, sizeof(int), \
  3820. \fi0         TRUE)) != KERN_SUCCESS) \{ \
  3821. \fi0     mach_error("vm_allocate returned value of ", ret); \
  3822. \fi0     printf("Exiting with error.\\n"); \
  3823. \fi0     exit(-1); \
  3824. \fi0 \} \
  3825. \fi0 if ((ret = vm_inherit(task_self(), (vm_address_t)lock, sizeof(int), \
  3826. \fi0         VM_INHERIT_SHARE)) != KERN_SUCCESS) \{ \
  3827. \fi0     mach_error("vm_inherit returned value of ", ret); \
  3828. \fi0     printf("Exiting with error.\\n"); \
  3829. \fi0     exit(-1); \
  3830. \fi0 \} \
  3831. \s25 \fi-2015 \f1 \fs28 \fs28 \
  3832. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The inheritance has been set.\
  3833. \fs20 \
  3834. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ADDRESS:  Illegal address specified.\
  3835. \fs20 \
  3836. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3837. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b task_create()\b0 , \b vm_region()\
  3838. \fs20 \
  3839. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  3840. \fs28 vm_protect()\
  3841. \fs20 \
  3842. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  3843. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Protect virtual memory\
  3844. \fs28 \
  3845. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  3846. \fs10 \
  3847. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b vm_protect(\b0 vm_task_t \i target_task\i0 , vm_address_t \i address\i0 , vm_size_t \i size\i0 , boolean_t \i set_maximum\i0 , vm_prot_t \i new_protection\b \i0 )\
  3848. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  3849. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i target_task\i0 :  Task whose virtual memory is to be affected.\
  3850. \fs20 \
  3851. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i address\i0 :  Starting address (this gets rounded down to a page boundary).\
  3852. \fs20 \
  3853. \fs28 \i size\i0 :  Size in bytes of the region for which protection is to change (this gets rounded up to a page boundary).\
  3854. \fs20 \
  3855. \fs28 \i set_maximum\i0 :  If set, make the protection change apply to the maximum protection associated with this address range; otherwise, change the current protection on this range.  If the maximum protection is reduced below the current protection, both will be changed to reflect the new maximum.\
  3856. \fs20 \
  3857. \fs28 \i new_protection\i0 :  A new protection value for this region; either VM_PROT_NONE or some combination of VM_PROT_READ, VM_PROT_WRITE, and VM_PROT_EXECUTE.\
  3858. \fs20 \
  3859. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3860. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b vm_protect()\b0  changes the protection of some pages of allocated memory in a task\'27s address space.  In general, a protection value permits the named operation.  When memory is first allocated it has all protection bits on.  The exact interpretation of a protection value is machine-dependent.  In the NeXT Mach operating system, three levels of memory protection are provided:  \
  3861. \fs20 \
  3862. \fs28 \pard \s8 \li2494 \fi-378 \ri1007 \ql \tx2494 \tx2872 \tx3250 \'b7    No access\
  3863. \'b7    Read and execute access\
  3864. \'b7    Read, execute, and write access\
  3865. \s4 \li2116 \fi0 \fs20 \
  3866. \fs28 VM_PROT_NONE permits no access.  VM_PROT_WRITE permits read, execute, and write access; VM_PROT_READ or VM_PROT_EXECUTE permits read and execute access, but not write access.  \
  3867. \fs20 \
  3868. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  3869. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 vm_address_t    addr = (vm_address_t)mlock;\
  3870. \fi0 \
  3871. \fi0 r = vm_protect(task_self(), addr, vm_page_size, FALSE, 0);\
  3872. \fi0 if (r != KERN_SUCCESS) \{\
  3873. \fi0     mach_error("vm_protect 0", r);\
  3874. \fi0     exit(1);\
  3875. \fi0 \}\
  3876. \fi0 printf("protect on\\n");\
  3877. \s25 \fi-2015 \f1 \fs28 \fs28 \
  3878. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The memory has been protected.\
  3879. \fs20 \
  3880. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_PROTECTION_FAILURE:  An attempt was made to increase the current or maximum protection beyond the existing maximum protection value.\
  3881. \fs20 \
  3882. \fs28 KERN_INVALID_ADDRESS:  An illegal or nonallocated address was specified.\
  3883. \fs20 \
  3884. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 \fs60 \
  3885. \fs28 vm_read()\
  3886. \fs20 \
  3887. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  3888. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Read virtual memory\
  3889. \fs28 \
  3890. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  3891. \fs10 \
  3892. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b vm_read(\b0 vm_task_t \i target_task\i0 , vm_address_t \i address\i0 , vm_size_t \i size\i0 , pointer_t *\i data\i0 , unsigned int *\i data_count\b \i0 )\
  3893. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  3894. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i target_task\i0 :  Task whose memory is to be read.\
  3895. \fs20 \
  3896. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i address\i0 :  The first address to be read (must be on a page boundary).\
  3897. \fs20 \
  3898. \fs28 \i size\i0 :  The number of bytes of data to be read (must be a multiple of \b vm_page_size\b0 ).\
  3899. \fs20 \
  3900. \fs28 \i data\i0 :  The array of data copied from the given task.\
  3901. \fs20 \
  3902. \fs28 \i data_count\i0 :  Returns the size of the data array in bytes (will be an integral number of pages).\
  3903. \fs20 \
  3904. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3905. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b vm_read()\b0  allows one task\'27s virtual memory to be read by another task.  The data array is returned in a newly allocated region; the task reading the data should call \b vm_deallocate()\b0  on this region when it\'27s done with the data.\
  3906. \fs20 \
  3907. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 For languages other than C, the value of \b vm_page_size\b0  can be obtained by calling \b vm_statistics()\b0 .\
  3908. \fs20 \
  3909. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  3910. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 if ((rtn = vm_allocate(task_self(), (vm_address_t *)&data1,\
  3911. \fi0         vm_page_size, TRUE)) != KERN_SUCCESS) \{ \
  3912. \fi0     mach_error("vm_allocate returned value of ", rtn); \
  3913. \fi0     printf("vmread: Exiting.\\n"); \
  3914. \fi0     exit(-1); \
  3915. \fi0 \}\
  3916. \pard \s14 \li2116 \fi0 \ri503 \ql \
  3917. temp = data1; \
  3918. \fi0 for (i = 0; (i < vm_page_size); i++) \
  3919. \fi0     temp[i] = i; \
  3920. \fi0 printf("Filled space allocated with some data.\\n"); \
  3921. \fi0 printf("Doing vm_read....\\n"); \
  3922. \fi0 if ((rtn = vm_read(task_self(), (vm_address_t)data1, vm_page_size,\
  3923. \fi0         (pointer_t *)&data2, &data_cnt)) != KERN_SUCCESS) \{ \
  3924. \fi0     mach_error("vm_read returned value of ", rtn); \
  3925. \fi0     printf("vmread: Exiting.\\n"); \
  3926. \fi0     exit(-1); \
  3927. \fi0 \} \
  3928. \fi0 printf("Successful vm_read.\\n");\
  3929. \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  3930. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The memory has been read.\
  3931. \fs20 \
  3932. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  Either \i address\i0  does not start on a page boundary or \i size\i0  isn\'27t an integral number of pages.\
  3933. \fs20 \
  3934. \fs28 KERN_NO_SPACE:  There isn\'27t enough room in the caller\'27s virtual memory to allocate space for the data to be returned.\
  3935. \fs20 \
  3936. \fs28 KERN_PROTECTION_FAILURE:  The address region in the target task is protected against reading.\
  3937. \fs20 \
  3938. \fs28 KERN_INVALID_ADDRESS:  An illegal or nonallocated address was specified, or there were not \i size\i0  bytes of data following that address.\
  3939. \fs20 \
  3940. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3941. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b vm_write()\b0 , \b vm_copy()\b0 , \b vm_deallocate()\
  3942. \fs20 \
  3943. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  3944. \fs28 vm_region()\
  3945. \fs20 \
  3946. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  3947. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get information about virtual memory regions\
  3948. \fs28 \
  3949. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  3950. \fs10 \
  3951. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b vm_region(\b0 vm_task_t \i target_task\i0 , vm_address_t *\i address\i0 , vm_size_t *\i size\i0 , vm_prot_t *\i protection\i0 , vm_prot_t *\i max_protection\i0 , vm_inherit_t\i  \i0 *\i inheritance\i0 , boolean_t *\i shared\i0 , port_t *\i object_name\i0 , vm_offset_t *\i offset\b \i0 )\
  3952. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  3953. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i target_task\i0 :  The task for which an address space description is requested.\
  3954. \fs20 \
  3955. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i address\i0 :  The address at which to start looking for a region.  On return, \i address\i0  will contain the start of the region (therefore, the value returned will be different from the value that was passed in if the specified region is part of a larger region).\
  3956. \fs20 \
  3957. \fs28 \i size\i0 :  Returns the size (in bytes) of the located region.\
  3958. \fs20 \
  3959. \fs28 \i protection\i0 :  Returns the current protection of the region.\
  3960. \fs20 \
  3961. \fs28 \i max_protection\i0 :  Returns the maximum allowable protection for this region.\
  3962. \fs20 \
  3963. \fs28 \i inheritance\i0 :  Returns the inheritance attribute for this region.\
  3964. \fs20 \
  3965. \fs28 \i shared\i0 :  Returns true if this region is shared, false if it isn\'27t.\
  3966. \fs20 \
  3967. \fs28 \i object_name\i0 :  Returns the port identifying the region\'27s memory object.\
  3968. \fs20 \
  3969. \fs28 \i offset\i0 :  Returns the offset into the pager object at which this region begins.\
  3970. \fs20 \
  3971. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  3972. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The \b vm_region()\b0  function returns a description of the specified region of the target task\'27s virtual address space.  This function begins at \i address\i0 , looking forward through memory until it comes to an allocated region.  (If \i address\i0  is in a region, that region is used.)  If \i address\i0  isn\'27t in a region, it\'27s set to the start of the first region that follows the incoming value.  In this way an entire address space can be scanned.  You can set \i address\i0  to the constant VM_MIN_ADDRESS (defined in the header file \b mach/machine/vm_param.h\b0 ) to specify the first address in the address space.  \
  3973. \fs20 \
  3974. \fs28 \s18 \f2 \fs24 \fs10 \
  3975. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 char          *data;\
  3976. \fi0 kern_return_t r;\
  3977. \fi0 vm_size_t     size;\
  3978. \fi0 vm_prot_t     protection, max_protection;\
  3979. \fi0 vm_inherit_t  inheritance;\
  3980. \fi0 boolean_t     shared;\
  3981. \fi0 port_t        object_name;\
  3982. \fi0 vm_offset_t   offset;\
  3983. \fi0 vm_address_t  address; \
  3984. \pard \s14 \li2116 \fi0 \ri503 \ql \
  3985. /* . . . */\
  3986. \fi0 /* Check the inheritance of "data". */\
  3987. \fi0 address = (vm_address_t)&data;\
  3988. \fi0 r = vm_region(task_self(), &address, &size, &protection, \
  3989. \fi0     &max_protection, &inheritance, &shared, &object_name, &offset);\
  3990. \fi0 \
  3991. if (r != KERN_SUCCESS)\
  3992. \fi0     mach_error("Error calling vm_region", r);\
  3993. \fi0 else \{\
  3994. \fi0     printf("Inheritance is:  ");\
  3995. \fi0     switch (inheritance) \{\
  3996. \fi0         case VM_INHERIT_SHARE:  \
  3997. \fi0             printf("Share with child\\n");\
  3998. \fi0             break;\
  3999. \fi0         case VM_INHERIT_COPY:  \
  4000. \fi0             printf("Copy into child\\n");\
  4001. \fi0             break;\
  4002. \fi0         case VM_INHERIT_NONE:  \
  4003. \fi0             printf("Absent from child\\n");\
  4004. \fi0             break;\
  4005. \fi0         case VM_INHERIT_DONATE_COPY:\
  4006. \fi0             printf("Copy and delete\\n");\
  4007. \fi0             break;\
  4008. \fi0     \}\
  4009. \fi0 \}\
  4010. \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  4011. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The region was located and information has been returned.\
  4012. \fs20 \
  4013. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_NO_SPACE:  The task contains no region at or above \i address\i0 .\
  4014. \fs20 \
  4015. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  4016. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b vm_allocate()\b0 , \b vm_deallocate()\b0 , \b vm_protect()\b0 , \b vm_inherit()\
  4017. \fs20 \
  4018. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  4019. \fs28 vm_set_policy()\
  4020. \fs20 \
  4021. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  4022. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Set the paging policy for a region of memory\
  4023. \fs28 \
  4024. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  4025. \fs10 \
  4026. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b vm_set_policy(\b0 vm_task_t \i target_task\i0 , vm_address_t \i address\i0 , vm_size_t \i size\i0 , int\i  policy\b \i0 )\
  4027. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  4028. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i target_task\i0 :  Task whose virtual memory is to be affected.\
  4029. \fs20 \
  4030. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i address\i0 :  Starting address (must be on a page boundary).\
  4031. \fs20 \
  4032. \fs28 \i size\i0 :  Number of bytes (must be a multiple of \b vm_page_size\b0 ).\
  4033. \fs20 \
  4034. \fs28 \i policy\i0 :  Mask specifying the paging policy.  Values for \i policy\i0  are defined in the header file \b mach/vm_policy.h\b0 .\
  4035. \fs20 \
  4036. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  4037. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 This function lets you control the paging policy for a region of memory.  In addition to its normal paging policy, the system can control the placement of pages under certain patterns of access.  These patterns are currently limited to strictly sequential access in either direction.\
  4038. \fs20 \
  4039. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 The \i policy\i0  mask can have the following values, which can be combined:\
  4040. \fs20 \
  4041. \fs28 \s8 \li2494 \fi-378 \'b7    VM_POLICY_PAGE_AHEAD (page ahead)\
  4042. \'b7    VM_POLICY_SEQ_DEACTIVATE (deactivate behind)\
  4043. \'b7    VM_POLICY_SEQ_FREE (free behind)\
  4044. \'b7    VM_POLICY_RANDOM (don\'27t use a special paging policy)\
  4045. \pard \s37 \li2116 \fi0 \ri1007 \ql \fs20 \
  4046. \fs28 \f0 \b \fs28 Note:  \b0 \fs28 \f1 The page-ahead policy isn\'27t currently implemented.\
  4047. \fs20 \
  4048. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Calls to \b vm_policy()\b0  affect memory at the backing store level, not the mapping level.  For example, calling \b vm_policy()\b0  on a memory-mapped file affects the underlying file, and consequently all uses of that file.  It is currently impossible for different users of the same file to have different policies for that file.\
  4049. \fs20 \
  4050. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  4051. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b vm_deactivate()\
  4052. \fs20 \
  4053. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  4054. \fs28 vm_statistics()\
  4055. \fs20 \
  4056. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  4057. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Examine virtual memory statistics\
  4058. \fs28 \
  4059. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  4060. \fs10 \
  4061. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b vm_statistics(\b0 vm_task_t \i target_task\i0 , vm_statistics_data_t *\i vm_stats\b \i0 )\
  4062. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  4063. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i target_task\i0 :  The task that\'27s requesting the statistics.\
  4064. \fs20 \
  4065. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i vm_stats\i0 :  Returns the statistics.\
  4066. \fs20 \
  4067. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  4068. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b vm_statistics()\b0  returns statistics about the kernel\'27s use of virtual memory since the kernel was booted.  The system page size is contained in both the \b pagesize\b0  field of the \i vm_status\i0  and the global variable \b vm_page_size\b0 , which is set at task initialization and remains constant for the life of the task.\
  4069. \fs20 \
  4070. \fs28 \pard \s12 \li2494 \fi0 \ri1007 \ql \f2 \fs24 struct vm_statistics \{\
  4071. \fi0     long  pagesize;        /* page size in bytes */ \
  4072. \fi0     long  free_count;      /* number of pages free */ \
  4073. \fi0     long  active_count;    /* number of pages active */ \
  4074. \fi0     long  inactive_count;  /* number of pages inactive */ \
  4075. \fi0     long  wire_count;      /* number of pages wired down */ \
  4076. \fi0     long  zero_fill_count; /* number of zero-fill pages */ \
  4077. \fi0     long  reactivations;   /* number of pages reactivated */ \
  4078. \fi0     long  pageins;         /* number of pageins */ \
  4079. \fi0     long  pageouts;        /* number of pageouts */ \
  4080. \fi0     long  faults;          /* number of faults */\
  4081. \fi0     long  cow_faults;      /* number of copy-on-writes */ \
  4082. \fi0     long  lookups;         /* object cache lookups */\
  4083. \fi0     long  hits;            /* object cache hits */\
  4084. \fi0 \};\
  4085. \fi0 typedef struct vm_statistics   vm_statistics_data_t;\
  4086. \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs28 \
  4087. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 result=vm_statistics(task_self(), &vm_stats);\
  4088. \fi0 if (result != KERN_SUCCESS)\
  4089. \fi0     mach_error("An error calling vm_statistics()!", result);\
  4090. \fi0 else\
  4091. \fi0     printf("%d bytes of RAM are free\\n", \
  4092. \fi0         vm_stats.free_count * vm_stats.pagesize); \
  4093. \s25 \fi-2015 \f1 \fs28 \fs28 \
  4094. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  The operation was successful.\
  4095. \fs20 \
  4096. \fs28 \s20 \fi0 \f0 \b \fs28 \fs60 \
  4097. \fs28 vm_write()\
  4098. \fs20 \
  4099. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  4100. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Write virtual memory\
  4101. \fs28 \
  4102. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  4103. \fs10 \
  4104. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b vm_write(\b0 vm_task_t \i target_task\i0 , vm_address_t \i address\i0 , pointer_t \i data\i0 , unsigned int \i data_count\b \i0 )\
  4105. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  4106. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i target_task\i0 :  Task whose memory is to be written.\
  4107. \fs20 \
  4108. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i address\i0 :  Starting address in task to be affected (must be a page boundary).\
  4109. \fs20 \
  4110. \fs28 \i data\i0 :  An array of bytes to be written.\
  4111. \fs20 \
  4112. \fs28 \i data_count\i0 :  The size in bytes of the data array (must be a multiple of \b vm_page_size\b0 ).\
  4113. \fs20 \
  4114. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  4115. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b vm_write()\b0  allows a task\'27s virtual memory to be written by another task.  For languages other than C, the value of \b vm_page_size\b0  can be obtained by calling \b vm_statistics()\b0 .\
  4116. \fs20 \
  4117. \fs28 \s25 \fs10 \
  4118. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 KERN_SUCCESS:  Memory written.\
  4119. \fs20 \
  4120. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 KERN_INVALID_ARGUMENT:  The address doesn\'27t start on a page boundary, or the size isn\'27t an integral number of pages.\
  4121. \fs20 \
  4122. \fs28 KERN_PROTECTION_FAILURE:  The address region in the target task is protected against writing.\
  4123. \fs20 \
  4124. \fs28 KERN_INVALID_ADDRESS:  An illegal or nonallocated address was specified or the amount of allocated memory starting at \i address\i0  was less than \i data_count\i0 .\
  4125. \fs20 \
  4126. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  4127. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b vm_copy()\b0 , \b vm_protect()\b0 , \b vm_read()\b0 , \b vm_statistics()\
  4128. \fs20 \
  4129. \fs28 \pard \s0 \li100 \fi0 \ri1007 \ql \f0 \fs48 \fs60 \
  4130. \fs48 Bootstrap Server Functions\
  4131. \fs28 \
  4132. \fs48 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \f1 \b0 \fs28 The Bootstrap Server, like the Network Name Server, lets tasks publish ports that other tasks can send messages to.  Unlike the Network Name Server, the Bootstrap Server is designed so that each server and its clients must be on the same host.  The Bootstrap Server accomplishes this by using each task\'27s bootstrap port (which is inherited from its parent) to ensure that the task is a descendent of a local task.  \
  4133. \fs20 \
  4134. \fs28 When a task forks a child task that shouldn\'27t have access to the same set of services as the parent, the parent task must change its own bootstrap port\'d0perhaps only temporarily\'d0so that its child inherits a \i subset port\i0 .  The parent should then change the set of services available on the subset port to suit the child\'27s requirements.\
  4135. \fs20 \
  4136. \fs28 The Bootstrap Server was created by NeXT, so these functions aren\'27t in other versions of Mach.  See \b /NextDeveloper/Headers/servers/bootstrap.defs\b0  for more information of how the Bootstrap Server works.\
  4137. \fs20 \
  4138. \fs28 \pard \s37 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Note:  \b0 \fs28 \f1 If possible, you should use Distributed Objects instead of the Bootstrap Server.  The Distributed Objects system is described in the \i NEXTSTEP General Reference\i0 .\
  4139. \fs20 \
  4140. \fs28 \s20 \f0 \b \fs28 \fs60 \
  4141. \fs28 bootstrap_check_in()\
  4142. \fs20 \
  4143. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  4144. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get receive rights to a service port\
  4145. \fs28 \
  4146. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  4147. \fi0 #import <servers/bootstrap.h>\
  4148. \fs10 \
  4149. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b bootstrap_check_in(\b0 port_t \i bootstrap_port\i0 , name_t \i service_name\i0 , port_all_t *\i service_port\b \i0 )\
  4150. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  4151. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i bootstrap_port\i0 :  A bootstrap port.  Usually, this should be the task\'27s default bootstrap port, which is returned by \b task_get_bootstrap_port()\b0 .\
  4152. \fs20 \
  4153. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i service_name\i0 :  The string that names the service.\
  4154. \fs20 \
  4155. \fs28 \i service_port\i0 :  Returns receive rights to the service port.\
  4156. \fs20 \
  4157. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  4158. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 Use this function in a server to start providing a service.  The service must already be defined, either by the appropriate line in \b /etc/bootstrap.conf\b0  or by a call to \b bootstrap_create_service()\b0 .  Calling \b bootstrap_check_in()\b0  makes the service active.  \
  4159. \fs20 \
  4160. \fs28 \s18 \f2 \fs24 \fs10 \
  4161. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 /* Get receive rights for our service. */\
  4162. \fi0 result=bootstrap_check_in(bootstrap_port, MYNAME, &my_service_port);\
  4163. \fi0 if (result != BOOTSTRAP_SUCCESS)\
  4164. \fi0     mach_error("Couldn\'27t create service", result);\
  4165. \s25 \fi-2015 \f1 \fs28 \fs28 \
  4166. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 BOOTSTRAP_SUCCESS:  The call succeeded.\
  4167. \fs20 \
  4168. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 BOOTSTRAP_NOT_PRIVILEGED:  \i bootstrap_port\i0  is an unprivileged bootstrap port.\
  4169. \fs20 \
  4170. \fs28 BOOTSTRAP_UNKNOWN_SERVICE:  The service doesn\'27t exist.  It might be defined in a subset (see \b bootstrap_subset()\b0 ).\
  4171. \fs20 \
  4172. \fs28 BOOTSTRAP_SERVICE_ACTIVE:  The service has already been registered or checked in and the server hasn\'27t died.\
  4173. \fs20 \
  4174. \fs28 Returns appropriate kernel errors on RPC failure.\
  4175. \fs20 \
  4176. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 \fs60 \
  4177. \fs28 bootstrap_create_service()\
  4178. \fs20 \
  4179. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  4180. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Create a service and service port\
  4181. \fs28 \
  4182. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  4183. \fi0 #import <servers/bootstrap.h>\
  4184. \fs10 \
  4185. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b bootstrap_create_service(\b0 port_t \i bootstrap_port\i0 , name_t \i service_name\i0 , port_t *\i service_port\b \i0 )\
  4186. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  4187. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i bootstrap_port\i0 :  A bootstrap port.  Usually, this should be the task\'27s default bootstrap port, which is returned by \b task_get_bootstrap_port()\b0 .\
  4188. \fs20 \
  4189. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i service_name\i0 :  The string that specifies the service.\
  4190. \fs20 \
  4191. \fs28 \i service_port\i0 :  Returns send rights for the service.\
  4192. \fs20 \
  4193. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  4194. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 Creates a service named \i service_name\i0  and returns send rights to that port in \i service_port\i0 .  The port may later be checked in as if this port were configured in the bootstrap configuration file.  (At that time \b bootstrap_check_in()\b0  will return receive rights to \i service_port \i0 and will make the service active.)\
  4195. \fs20 \
  4196. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 This function is often used to create services that are available only to a subset of tasks (see \b bootstrap_subset()\b0 ).  Any task can call this function\'d0it doesn\'27t have to be the server.\
  4197. \fs20 \
  4198. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  4199. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 /* Tell the bootstrap server about a service. */\
  4200. \fi0 result=bootstrap_create_service(bootstrap_port, SERVICENAME, \
  4201. \fi0     &service_port);\
  4202. \fi0 if (result!=BOOTSTRAP_SUCCESS)\
  4203. \fi0     mach_error("Couldn\'27t create service", result);\
  4204. \s25 \fi-2015 \f1 \fs28 \fs28 \
  4205. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 BOOTSTRAP_SUCCESS:  The call succeeded.\
  4206. \fs20 \
  4207. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 BOOTSTRAP_NOT_PRIVILEGED:  \i bootstrap_port\i0  is an unprivileged bootstrap port.\
  4208. \fs20 \
  4209. \fs28 BOOTSTRAP_SERVICE_ACTIVE:  The service already exists.\
  4210. \fs20 \
  4211. \fs28 Returns appropriate kernel errors on RPC failure.  \
  4212. \fs20 \
  4213. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 \fs60 \
  4214. \fs28 bootstrap_info()\
  4215. \fs20 \
  4216. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  4217. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get information about all known services\
  4218. \fs28 \
  4219. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  4220. \fi0 #import <servers/bootstrap.h>\
  4221. \fs10 \
  4222. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b bootstrap_info(\b0 port_t \i bootstrap_port\i0 , name_array_t *\i service_names\i0 , unsigned int *\i service_names_count\i0 , name_array_t *\i server_names\i0 , unsigned int *\i server_names_count\i0 , bool_array_t *\i service_active\i0 , unsigned int *\i service_active_count\b \i0 )\
  4223. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  4224. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i bootstrap_port\i0 :  A bootstrap port.  Usually, this should be the task\'27s default bootstrap port, which is returned by \b task_get_bootstrap_port()\b0 .\
  4225. \fs20 \
  4226. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i service_names\i0 :  Returns the names of all known services.\
  4227. \fs20 \
  4228. \fs28 \i service_names_count\i0 :  Returns the number of service names.\
  4229. \fs20 \
  4230. \fs28 \i server_names\i0 :  Returns the name, if known, of the server that provides the corresponding service.  Except for the \b mach_init\b0  server, this name isn\'27t known unless the bootstrap configuration file has a \b server\b0  line for this server.\
  4231. \fs20 \
  4232. \fs28 \i server_names_count\i0 :  Returns the number of server names.\
  4233. \fs20 \
  4234. \fs28 \i service_active\i0 :  Returns an array of booleans that correspond to the \i service_names\i0  array.  For each item, the boolean value is true if the service is receiving messages sent to its port; otherwise, it\'27s false.\
  4235. \fs20 \
  4236. \fs28 \i service_active_count\i0 :  Returns the number of items in the \i service_active\i0  array.\
  4237. \fs20 \
  4238. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  4239. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 This function returns information about all services that are known.  Note that it won\'27t return information on services that are defined only in subsets, unless the subset port is an ancestor of \i bootstrap_port\i0 .  (See \b bootstrap_subset()\b0  for information on subsets.)\
  4240. \fs20 \
  4241. \fs28 \s18 \f2 \fs24 \fs10 \
  4242. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 result = bootstrap_info(bootstrap_port, &service_names, &service_cnt,\
  4243. \fi0   &server_names, &server_cnt, &service_active, &service_active_cnt);\
  4244. \fi0 if (result != BOOTSTRAP_SUCCESS)\
  4245. \fi0     printf("ERROR:  info failed: %d", result);\
  4246. \fi0 else \{\
  4247. \fi0     for (i = 0; i < service_cnt; i++)\
  4248. \fi0         printf("Name: %-15s   Server: %-15s    Active: %-4s",\
  4249. \fi0             service_names[i],\
  4250. \fi0             server_names[i][0] == \'27\\0\'27 ? "Unknown" : server_names[i],\
  4251. \fi0             service_active[i] ? "Yes\\n" : "No\\n");\
  4252. \fi0 \}\
  4253. \s25 \fi-2015 \f1 \fs28 \fs28 \
  4254. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 BOOTSTRAP_SUCCESS:  The call succeeded.\
  4255. \fs20 \
  4256. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 BOOTSTRAP_NO_MEMORY:  The Bootstrap Server couldn\'27t allocate enough memory to return the information.\
  4257. \fs20 \
  4258. \fs28 Returns appropriate kernel errors on RPC failure.  \
  4259. \fs20 \
  4260. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 \fs60 \
  4261. \fs28 bootstrap_look_up()\
  4262. \fs20 \
  4263. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  4264. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get the service port of a particular service\
  4265. \fs28 \
  4266. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  4267. \fi0 #import <servers/bootstrap.h>\
  4268. \fs10 \
  4269. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b bootstrap_look_up(\b0 port_t \i bootstrap_port\i0 , name_t \i service_name\i0 , port_t *\i service_port\b \i0 )\
  4270. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  4271. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i bootstrap_port\i0 :  A bootstrap port.  Usually, this should be the task\'27s default bootstrap port, which is returned by \b task_get_bootstrap_port()\b0 .\
  4272. \fs20 \
  4273. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i service_name\i0 :  The string that identifies the service.\
  4274. \fs20 \
  4275. \fs28 \i service_port\i0 :  Returns send rights for the service port.\
  4276. \fs20 \
  4277. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  4278. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 Returns send rights for the service port of the specified service.  The service isn\'27t guaranteed to be active.  (To check whether the service is active, use \b bootstrap_status()\b0 .)\
  4279. \fs20 \
  4280. \fs28 \s18 \f2 \fs24 \fs10 \
  4281. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 result=bootstrap_look_up(bootstrap_port, "FreeService2", &srvc_port);\
  4282. \fi0 if (result!=BOOTSTRAP_SUCCESS)\
  4283. \fi0     printf("lookup failed: %d\\n", result);\
  4284. \fi0 else \{\
  4285. \fi0     /* Access the service by sending messages to srvc_port. */\
  4286. \fi0 \}\
  4287. \s25 \fi-2015 \f1 \fs28 \fs28 \
  4288. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 BOOTSTRAP_SUCCESS:  The call succeeded.\
  4289. \fs20 \
  4290. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 BOOTSTRAP_UNKNOWN_SERVICE:  The service doesn\'27t exist.  It might be defined in a subset (see \b bootstrap_subset()\b0 ).\
  4291. \fs20 \
  4292. \fs28 Returns appropriate kernel errors on RPC failure.  \
  4293. \fs20 \
  4294. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 \fs60 \
  4295. \fs28 bootstrap_look_up_array()\
  4296. \fs20 \
  4297. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  4298. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get the service ports for an array of services\
  4299. \fs28 \
  4300. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  4301. \fi0 #import <servers/bootstrap.h>\
  4302. \fs10 \
  4303. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b bootstrap_look_up_array(\b0 port_t \i bootstrap_port\i0 , name_array_t \i service_names\i0 , unsigned int \i service_names_count\i0 , port_array_t *\i service_ports\i0 , unsigned int *\i service_ports_count\i0 , boolean_t *\i all_services_known\b \i0 )\
  4304. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  4305. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i bootstrap_port\i0 :  A bootstrap port.    Usually, this should be the task\'27s default bootstrap port, which is returned by \b task_get_bootstrap_port()\b0 .\
  4306. \fs20 \
  4307. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i service_names\i0 :  An array of service names.\
  4308. \fs20 \
  4309. \fs28 \i service_names_count\i0 :  The number of service names.\
  4310. \fs20 \
  4311. \fs28 \i service_ports\i0 :  Returns an array of service ports.  \
  4312. \fs20 \
  4313. \fs28 \i service_ports_count\i0 :  Returns the number of service ports.  This should be equal to \i service_names_count\i0 .\
  4314. \fs20 \
  4315. \fs28 \i all_services_known\i0 :  Returns true if every service name was recognized; otherwise returns false.\
  4316. \fs20 \
  4317. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  4318. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 Returns port send rights in corresponding entries of the array \i service_ports\i0  for all services named in the array \i service_names\i0 .  You should call \b vm_deallocate()\b0  on \i service_ports\i0  when you no longer need it.\
  4319. \fs20 \
  4320. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 Unknown service names have the corresponding service port set to PORT_NULL.  Note that these services might be available in a subset (see \b bootstrap_subset()\b0 ).\
  4321. \fs20 \
  4322. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  4323. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 kern_return_t   result;\
  4324. \fi0 port_t          my_bootstrap_port;\
  4325. \fi0 unsigned int    port_cnt;\
  4326. \fi0 boolean_t       all_known;\
  4327. \fi0 name_t          name_array[2]=\{"Service", "NetMessage"\};\
  4328. \fi0 port_array_t    ports;\
  4329. \pard \s14 \li2116 \fi0 \ri503 \ql \
  4330. result = task_get_bootstrap_port(task_self(), &my_bootstrap_port);\
  4331. \fi0 if (result != KERN_SUCCESS) \{\
  4332. \fi0     mach_error("Couldn\'27t get bootstrap port", result);\
  4333. \fi0     exit(1);\
  4334. \fi0 \}\
  4335. \fi0 \
  4336. result=bootstrap_look_up_array(my_bootstrap_port, name_array, 2,\
  4337. \fi0     &ports, &port_cnt, &all_known);\
  4338. \fi0 if (result!=BOOTSTRAP_SUCCESS)\
  4339. \fi0     mach_error("Lookup array failed", result);\
  4340. \fi0 else \
  4341. \fi0     printf("Port count = %d, all known = %d\\n", port_cnt, all_known);\
  4342. \fi0 \
  4343. /* . . . */\
  4344. \fi0 result=vm_deallocate(task_self(), (vm_address_t)ports, \
  4345. \fi0     sizeof(ports)*port_cnt);\
  4346. \fi0 if (result != KERN_SUCCESS)\
  4347. \fi0     mach_error("Trouble freeing ports", result);\
  4348. \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  4349. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 BOOTSTRAP_SUCCESS:  The call succeeded.\
  4350. \fs20 \
  4351. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 BOOTSTRAP_BAD_COUNT:  \i service_names_count\i0  was too large (greater than BOOTSTRAP_MAX_LOOKUP_COUNT, which is defined in the header file \b server/bootstrap_defs.h\b0 ).\
  4352. \fs20 \
  4353. \fs28 Returns appropriate kernel errors on RPC failure.  \
  4354. \fs20 \
  4355. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 \fs60 \
  4356. \fs28 bootstrap_register()\
  4357. \fs20 \
  4358. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  4359. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Register send rights for a service port \
  4360. \fs28 \
  4361. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  4362. \fi0 #import <servers/bootstrap.h>\
  4363. \fs10 \
  4364. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b bootstrap_register(\b0 port_t \i bootstrap_port\i0 , name_t \i service_name\i0 , port_t \i service_port\b \i0 )\
  4365. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  4366. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i bootstrap_port\i0 :  A bootstrap port.  Usually, this should be the task\'27s default bootstrap port, which is returned by \b task_get_bootstrap_port()\b0 .\
  4367. \fs20 \
  4368. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i service_name\i0 :  The string that identifies the service.\
  4369. \fs20 \
  4370. \fs28 \i service_port\i0 :  The service port for the service.\
  4371. \fs20 \
  4372. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  4373. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 You can use this function to create a server that hasn\'27t been defined in the bootstrap configuration file.  This function specifies to the Bootstrap Server exactly which port should be the service port.\
  4374. \fs20 \
  4375. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 You can\'27t register a service if an active binding already exists.  However, you can register a service if the existing binding is inactive (that is, the Bootstrap Server currently holds receive rights for the service port); in this case the previous service port will be deallocated.  \
  4376. \fs20 \
  4377. \fs28 A service that is restarting can resume service for previous clients by setting \i service_port\i0  to the previous service port.  You can get this port by calling \b bootstrap_check_in()\b0 .\
  4378. \fs20 \
  4379. \fs28 \pard \s18 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f2 \fs24 \fs10 \
  4380. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 /* Create a port to use as the service port. */\
  4381. \fi0 result=port_allocate(task_self(), &myport);\
  4382. \fi0 if (result != KERN_SUCCESS) \{\
  4383. \fi0     mach_error("Couldn\'27t allocate a service port", result);\
  4384. \fi0     exit(1);\
  4385. \fi0 \}\
  4386. \fi0 \
  4387. \fi0 /* Tell the bootstrap server about my service. */\
  4388. \fi0 result=bootstrap_register(bootstrap_port, MYNAME, myport);\
  4389. \fi0 if (result != BOOTSTRAP_SUCCESS)\
  4390. \fi0     printf("Call to bootstrap_register failed: %d", result);\
  4391. \s25 \fi-2015 \f1 \fs28 \fs28 \
  4392. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 BOOTSTRAP_SUCCESS:  The call succeeded.\
  4393. \fs20 \
  4394. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 BOOTSTRAP_NOT_PRIVILEGED:  \i bootstrap_port\i0  is an unprivileged bootstrap port.\
  4395. \fs20 \
  4396. \fs28 BOOTSTRAP_NAME_IN_USE:  The service is already active.  \
  4397. \fs20 \
  4398. \fs28 Returns appropriate kernel errors on RPC failure.  \
  4399. \fs20 \
  4400. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 \fs60 \
  4401. \fs28 bootstrap_status()\
  4402. \fs20 \
  4403. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  4404. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Check whether a service is available\
  4405. \fs28 \
  4406. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  4407. \fi0 #import <servers/bootstrap.h>\
  4408. \fs10 \
  4409. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b bootstrap_status(\b0 port_t \i bootstrap_port\i0 , name_t \i service_name\i0 , boolean_t *\i service_active\i0 \'b0\b )\
  4410. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  4411. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i bootstrap_port\i0 :  A bootstrap port.  Usually, this should be the task\'27s default bootstrap port, which is returned by \b task_get_bootstrap_port()\b0 .\
  4412. \fs20 \
  4413. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i service_name\i0 :  The string that specifies a particular service.\
  4414. \fs20 \
  4415. \fs28 \i service_active\i0 :  Returns true if the service is active; otherwise, returns false.\
  4416. \fs20 \
  4417. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  4418. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 This function tells you whether a service is known to users of \i bootstrap_port\i0 , and whether it\'27s active.  A service is active if a server is able to receive messages on its service port.  If a service isn\'27t active, the Bootstrap Server holds receive rights for the service port.\
  4419. \fs20 \
  4420. \fs28 \s18 \f2 \fs24 \fs10 \
  4421. \fs24 \f0 \b \fs20     EXAMPLE    \b0 \fs24 \f2 result=bootstrap_status(bootstrap_port, MYNAME, &service_active);\
  4422. \fi0 if (result!=BOOTSTRAP_SUCCESS)\
  4423. \fi0     printf("status check failed\\n");\
  4424. \fi0 else \{\
  4425. \fi0     if (service_active)\
  4426. \fi0         printf("Server %s is active\\n", MYNAME);\
  4427. \fi0     else\
  4428. \fi0         printf ("Server %s is NOT active\\n", MYNAME);\
  4429. \fi0 \}\
  4430. \s25 \fi-2015 \f1 \fs28 \fs28 \
  4431. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 BOOTSTRAP_SUCCESS:  The call succeeded.\
  4432. \fs20 \
  4433. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 BOOTSTRAP_UNKNOWN_SERVICE:  The service doesn\'27t exist.  It might be defined in a subset (see \b bootstrap_subset()\b0 ).\
  4434. \fs20 \
  4435. \fs28 Returns appropriate kernel errors on RPC failure.  \
  4436. \fs20 \
  4437. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 \fs60 \
  4438. \fs28 bootstrap_subset()\
  4439. \fs20 \
  4440. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  4441. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Get a new port to use as a bootstrap port\
  4442. \fs28 \
  4443. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  4444. \fi0 #import <servers/bootstrap.h>\
  4445. \fs10 \
  4446. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b bootstrap_subset(\b0 port_t \i bootstrap_port\i0 , port_t \i requestor_port\i0 , port_t *\i subset_port\b \i0 )\
  4447. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  4448. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i bootstrap_port\i0 :  A bootstrap port.  Usually, this should be the task\'27s default bootstrap port, which is returned by \b task_get_bootstrap_port()\b0 .\
  4449. \fs20 \
  4450. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i requestor_port\i0 :  A port that determines the life span of the subset.  \
  4451. \fs20 \
  4452. \fs28 \i subset_port\i0 :  Returns the subset port.\
  4453. \fs20 \
  4454. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  4455. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 Returns a new port to use as a bootstrap port.  This port behaves exactly like the previous \i bootstrap_port\i0 , with one exception:  When you register a port by calling \b bootstrap_register()\b0  using \i subset_port\i0  as the bootstrap port, the registered port is available only to users of \i subset_port\i0  and its descendants.  Lookups on the \i subset_port\i0  will return ports registered specifically with this port, and will also return ports registered with ancestors of this \i subset_port\i0 .  (The ancestors of \i subset_port\i0  are \i bootstrap_port\i0  and, if \i bootstrap_port\i0  is itself a subset port, any ancestors of \i bootstrap_port\i0 .) \
  4456. \fs20 \
  4457. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 You can override a service already registered with an ancestor port by registering it with the subset port.  Any thread that looks up the service using the subset port will see only the version of the service that\'27s registered with the subset port.  This is one way to transparently provide services such as monitor programs or individualized spelling checkers, while the rest of the system still uses the default service.  \
  4458. \fs20 \
  4459. \fs28 When it's detected that \i requestor_port\i0  is destroyed, the subset port and its descendants are destroyed; the services advertised by these ports are destroyed, as well.\
  4460. \fs20 \
  4461. \fs28 \pard \s14 \li2116 \fi0 \ri503 \ql \f2 \fs24 /* Get and save the current bootstrap port for this task. */\
  4462. \fi0 r = task_get_bootstrap_port(task_self(), &old_bs_port);\
  4463. \fi0 if (r != KERN_SUCCESS) \{\
  4464. \fi0     mach_error("task_get_bootstrap_port", r);\
  4465. \fi0     exit(1);\
  4466. \fi0 \} \
  4467. \fi0 /* Get a subset port. */\
  4468. \fi0 r = bootstrap_subset(old_bs_port, task_self(), &subset_port);\
  4469. \fi0 if (r != BOOTSTRAP_SUCCESS) \{\
  4470. \fi0     mach_error("Couldn't get unpriv port", r);\
  4471. \fi0     exit(1);\
  4472. \fi0 \}\
  4473. \fi0 \
  4474. /* Set the bootstrap port */\
  4475. \fi0 r = task_set_bootstrap_port(task_self(), subset_port);\
  4476. \fi0 if (r != KERN_SUCCESS) \{\
  4477. \fi0     mach_error("task_set_bootstrap_port", r);\
  4478. \fi0     exit(1);\
  4479. \fi0 \}\
  4480. \fi0 bootstrap_port = subset_port;\
  4481. \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \fs28 \fs28 \
  4482. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 BOOTSTRAP_SUCCESS:  The call succeeded.\
  4483. \fs20 \
  4484. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 BOOTSTRAP_NOT_PRIVILEGED:  \i bootstrap_port\i0  is an unprivileged bootstrap port.\
  4485. \fs20 \
  4486. \fs28 Returns appropriate kernel errors on RPC failure.  \
  4487. \fs20 \
  4488. \fs28 \pard \s0 \li100 \fi0 \ri1007 \ql \f0 \b \fs48 \fs60 \
  4489. \fs48 Network Name Server Functions\
  4490. \fs28 \
  4491. \fs48 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \f1 \b0 \fs28 If possible, you should use Distributed Objects instead of the Network Name Server functions.  The Distributed Objects system is described in the \i NEXTSTEP General Reference\i0 .  \
  4492. \fs20 \
  4493. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 \fs60 \
  4494. \fs28 netname_check_in()\
  4495. \fs20 \
  4496. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  4497. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Check a name into the local name space\
  4498. \fs28 \
  4499. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  4500. \fi0 #import <servers/netname.h>\
  4501. \fs10 \
  4502. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b netname_check_in(\b0 port_t \i server_port\i0 , netname_name_t \i port_name\i0 , port_t \i signature\i0 , port_t \i port_id\b \i0 )\
  4503. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  4504. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i server_port\i0 :  The task\'27s port to the Network Name Server.  To use the system Network Name Server, this should be set to the global variable \b name_server_port\b0 .\
  4505. \fs20 \
  4506. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i port_name\i0 :  The name of the port to be checked in.\
  4507. \fs20 \
  4508. \fs28 \i signature\i0 :  The port used to protect the right to remove a name.\
  4509. \fs20 \
  4510. \fs28 \i port_id\i0 :  The port to be checked in.\
  4511. \fs20 \
  4512. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  4513. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b netname_check_in()\b0  enters a port with the name \i port_name\i0  into the name space of the local network server.  The \i signature\i0  argument is a port that\'27s used to protect this name.  This same port must be presented on a \b netname_check_out()\b0  call for that call to be able to remove the name from the name space.\
  4514. \fs20 \
  4515. \fs28 \s25 \fs10 \
  4516. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 NETNAME_SUCCESS:  The operation succeeded.\
  4517. \fs20 \
  4518. \fs28 \s26 \fs10 \
  4519. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b netname_check_out()\b0 , \b netname_look_up()\
  4520. \fs20 \
  4521. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  4522. \fs28 netname_check_out()\
  4523. \fs20 \
  4524. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  4525. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Remove a name from the local name space\
  4526. \fs28 \
  4527. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  4528. \fi0 #import <servers/netname.h>\
  4529. \fs10 \
  4530. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b netname_check_out(\b0 port_t \i server_port\i0 , netname_name_t \i port_name\i0 , port_t \i signature\b \i0 )\
  4531. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  4532. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i server_port\i0 :  The task\'27s port to the Network Name Server.  To use the system Network Name Server, this should be set to \b name_server_port\b0 .\
  4533. \fs20 \
  4534. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i port_name\i0 :  The name of the port to be checked out.\
  4535. \fs20 \
  4536. \fs28 \i signature\i0 :  The port used to protect the right to remove a name.\
  4537. \fs20 \
  4538. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  4539. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b netname_check_out()\b0  removes a port with the name \i port_name\i0  from the name space of the local network server.  The \i signature\i0  argument must be the same port as the signature port passed to \b netname_check_in()\b0  when this name was checked in.\
  4540. \fs20 \
  4541. \fs28 \s25 \fs10 \
  4542. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 NETNAME_SUCCESS:  The operation succeeded.\
  4543. \fs20 \
  4544. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 NETNAME_NOT_YOURS:  The signature given to \b netname_check_out()\b0  did not match the signature with which the port was checked in.\
  4545. \fs20 \
  4546. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  4547. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b netname_check_in()\b0 , \b netname_look_up()\
  4548. \fs20 \
  4549. \fs28 \pard \s20 \li2116 \fi0 \ri1007 \ql \f0 \fs28 \fs60 \
  4550. \fs28 netname_look_up()\
  4551. \fs20 \
  4552. \fs28 \pard \s27 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \f1 \b0 \fs28 \fs10 \
  4553. \fs28 \f0 \b \fs20     SUMMARY    \b0 \fs28 \f1 Look up a name on a specific host\
  4554. \fs28 \
  4555. \fs28 \s28 \b \f0 \fs20     SYNOPSIS    \fs28 \f1 #import <mach/mach.h>\
  4556. \fi0 #import <servers/netname.h>\
  4557. \fs10 \
  4558. \fs28 \pard \s34 \li2494 \fi-378 \ri1007 \ql \b0 kern_return_t \b netname_look_up(\b0 port_t \i server_port\i0 , netname_name_t \i host_name\i0 , netname_name_t \i port_name\i0 , port_t *\i port_id\b \i0 )\
  4559. \pard \s15 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \b0 \fs28 \
  4560. \fs28 \f0 \b \fs20     ARGUMENTS    \b0 \fs28 \f1 \i server_port\i0 :  The task\'27s port to the Network Name Server.  To use the system Network Name Server, this should be set to \b name_server_port\b0 .\
  4561. \fs20 \
  4562. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 \i host_name\i0 :  The name of the host to query.  This can\'27t be a null pointer.\
  4563. \fs20 \
  4564. \fs28 \i port_name\i0 :  The name of port to be looked up.\
  4565. \fs20 \
  4566. \fs28 \i port_id\i0 :  The port that was looked up.\
  4567. \fs20 \
  4568. \fs28 \pard \s16 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  4569. \fs28 \f0 \b \fs20     DESCRIPTION    \b0 \fs28 \f1 The function \b netname_look_up()\b0  returns the value of the port named by \i port_name\i0  by questioning the host named by the \i host_name\i0  argument.  Thus this call is a directed name lookup.  The \i host_name\i0  may be any of the host\'27s official nicknames.  If it\'27s an empty string, the local host is assumed.  If \i host_name\i0  is \'aa\b *\b0 \'ba, a broadcast lookup is performed.\
  4570. \fs20 \
  4571. \fs28 \pard \s36 \li2116 \fi0 \ri1007 \ql \f0 \b \fs28 Important:  \b0 \fs28 \f1 Use \b NXPortNameLookup()\b0  instead of \b netname_look_up()\b0  in all NEXTSTEP applications.  (In the future, Listener instances might register with a server other than the Network Name Server.)\
  4572. \fs20 \
  4573. \fs28 \pard \s25 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  4574. \fs28 \f0 \b \fs20     RETURN    \b0 \fs28 \f1 NETNAME_SUCCESS:  The operation succeeded.\
  4575. \fs20 \
  4576. \fs28 \pard \s4 \li2116 \fi0 \ri1007 \ql \tx2494 \tx2872 \tx3250 NETNAME_NOT_CHECKED_IN:  \b netname_look_up()\b0  could not find the name at the given host.\
  4577. \fs20 \
  4578. \fs28 NETNAME_NO_SUCH_HOST:  The \i host_name\i0  argument to \b netname_look_up()\b0  does not name a valid host.\
  4579. \fs20 \
  4580. \fs28 NETNAME_HOST_NOT_FOUND:  \b netname_look_up()\b0  could not reach the host named by \i host_name\i0  (for instance, because it\'27s down).\
  4581. \fs20 \
  4582. \fs28 \pard \s26 \li2116 \fi-2015 \ri1007 \ql \tx1738 \tx2116 \fs10 \
  4583. \fs28 \f0 \b \fs20     SEE ALSO    \b0 \fs28 \f1 \b netname_check_in()\b0 , \b netname_check_out()\
  4584. \fs20 \
  4585. \fs28 }
  4586.